15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_host.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_backend_impl.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_policy.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_request_handler.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillCacheInfo(const AppCache* cache,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const GURL& manifest_url,
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   AppCacheStatus status, AppCacheInfo* info) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->manifest_url = manifest_url;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->status = status;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->cache_id = cache->cache_id();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache->is_complete())
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(cache->owning_group());
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->is_complete = true;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->group_id = cache->owning_group()->group_id();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->last_update_time = cache->update_time();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->creation_time = cache->owning_group()->creation_time();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->size = cache->cache_size();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // Anonymous namespace
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheHost::AppCacheHost(int host_id, AppCacheFrontend* frontend,
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           AppCacheServiceImpl* service)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : host_id_(host_id),
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      spawning_host_id_(kAppCacheNoHostId), spawning_process_id_(0),
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      parent_host_id_(kAppCacheNoHostId), parent_process_id_(0),
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pending_main_resource_cache_id_(kAppCacheNoCacheId),
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pending_selected_cache_id_(kAppCacheNoCacheId),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frontend_(frontend), service_(service),
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      storage_(service->storage()),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_callback_param_(NULL),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      main_resource_was_namespace_entry_(false),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      main_resource_blocked_(false),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      associated_cache_info_pending_(false) {
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service_->AddObserver(this);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheHost::~AppCacheHost() {
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  service_->RemoveObserver(this);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(Observer, observers_, OnDestructionImminent(this));
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (associated_cache_.get())
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_cache_->UnassociateHost(this);
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (group_being_updated_.get())
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group_being_updated_->RemoveUpdateObserver(this);
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  storage()->CancelDelegateCallbacks(this);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (service()->quota_manager_proxy() && !origin_in_use_.is_empty())
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service()->quota_manager_proxy()->NotifyOriginNoLongerInUse(origin_in_use_);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::AddObserver(Observer* observer) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.AddObserver(observer);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::RemoveObserver(Observer* observer) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.RemoveObserver(observer);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::SelectCache(const GURL& document_url,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const int64 cache_document_was_loaded_from,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const GURL& manifest_url) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_start_update_callback_.is_null() &&
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_swap_cache_callback_.is_null() &&
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_get_status_callback_.is_null() &&
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         !is_selection_pending());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  origin_in_use_ = document_url.GetOrigin();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (service()->quota_manager_proxy() && !origin_in_use_.is_empty())
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service()->quota_manager_proxy()->NotifyOriginInUse(origin_in_use_);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (main_resource_blocked_)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frontend_->OnContentBlocked(host_id_,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                blocked_manifest_url_);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.6 The application cache selection algorithm.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The algorithm is started here and continues in FinishCacheSelection,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after cache or group loading is complete.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: Foreign entries are detected on the client side and
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MarkAsForeignEntry is called in that case, so that detection
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // step is skipped here. See WebApplicationCacheHostImpl.cc
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (cache_document_was_loaded_from != kAppCacheNoCacheId) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadSelectedCache(cache_document_was_loaded_from);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!manifest_url.is_empty() &&
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (manifest_url.GetOrigin() == document_url.GetOrigin())) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!first_party_url_.is_empty());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCachePolicy* policy = service()->appcache_policy();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy &&
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !policy->CanCreateAppCache(manifest_url, first_party_url_)) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FinishCacheSelection(NULL, NULL);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<int> host_ids(1, host_id_);
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      frontend_->OnEventRaised(host_ids, APPCACHE_CHECKING_EVENT);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frontend_->OnErrorEventRaised(
119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          host_ids,
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          AppCacheErrorDetails(
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              "Cache creation was blocked by the content policy",
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              APPCACHE_POLICY_ERROR,
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              GURL(),
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              0,
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              false /*is_cross_origin*/));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frontend_->OnContentBlocked(host_id_, manifest_url);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: The client detects if the document was not loaded using HTTP GET
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and invokes SelectCache without a manifest url, so that detection step
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is also skipped here. See WebApplicationCacheHostImpl.cc
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_preferred_manifest_url(manifest_url);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_master_entry_url_ = document_url;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadOrCreateGroup(manifest_url);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): If there was a manifest URL, the user agent may report
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the user that it was ignored, to aid in application development.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FinishCacheSelection(NULL, NULL);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::SelectCacheForWorker(int parent_process_id,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int parent_host_id) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_start_update_callback_.is_null() &&
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_swap_cache_callback_.is_null() &&
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_get_status_callback_.is_null() &&
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         !is_selection_pending());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_process_id_ = parent_process_id;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_host_id_ = parent_host_id;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FinishCacheSelection(NULL, NULL);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::SelectCacheForSharedWorker(int64 appcache_id) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_start_update_callback_.is_null() &&
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_swap_cache_callback_.is_null() &&
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_get_status_callback_.is_null() &&
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         !is_selection_pending());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (appcache_id != kAppCacheNoCacheId) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadSelectedCache(appcache_id);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FinishCacheSelection(NULL, NULL);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(michaeln): change method name to MarkEntryAsForeign for consistency
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::MarkAsForeignEntry(const GURL& document_url,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int64 cache_document_was_loaded_from) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The document url is not the resource url in the fallback case.
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  storage()->MarkEntryAsForeign(
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      main_resource_was_namespace_entry_ ? namespace_entry_url_ : document_url,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cache_document_was_loaded_from);
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SelectCache(document_url, kAppCacheNoCacheId, GURL());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::GetStatusWithCallback(const GetStatusCallback& callback,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         void* callback_param) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_start_update_callback_.is_null() &&
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_swap_cache_callback_.is_null() &&
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_get_status_callback_.is_null());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_get_status_callback_ = callback;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_callback_param_ = callback_param;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_selection_pending())
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoPendingGetStatus();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::DoPendingGetStatus() {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(false, pending_get_status_callback_.is_null());
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_get_status_callback_.Run(GetStatus(), pending_callback_param_);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_get_status_callback_.Reset();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_callback_param_ = NULL;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::StartUpdateWithCallback(const StartUpdateCallback& callback,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           void* callback_param) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_start_update_callback_.is_null() &&
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_swap_cache_callback_.is_null() &&
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_get_status_callback_.is_null());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_start_update_callback_ = callback;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_callback_param_ = callback_param;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_selection_pending())
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoPendingStartUpdate();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::DoPendingStartUpdate() {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(false, pending_start_update_callback_.is_null());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.8 Application cache API
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = false;
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (associated_cache_.get() && associated_cache_->owning_group()) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheGroup* group = associated_cache_->owning_group();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!group->is_obsolete() && !group->is_being_deleted()) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = true;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      group->StartUpdate();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_start_update_callback_.Run(success, pending_callback_param_);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_start_update_callback_.Reset();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_callback_param_ = NULL;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::SwapCacheWithCallback(const SwapCacheCallback& callback,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         void* callback_param) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_start_update_callback_.is_null() &&
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_swap_cache_callback_.is_null() &&
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pending_get_status_callback_.is_null());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_swap_cache_callback_ = callback;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_callback_param_ = callback_param;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_selection_pending())
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoPendingSwapCache();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::DoPendingSwapCache() {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(false, pending_swap_cache_callback_.is_null());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.8 Application cache API
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = false;
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (associated_cache_.get() && associated_cache_->owning_group()) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (associated_cache_->owning_group()->is_obsolete()) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = true;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AssociateNoCache(GURL());
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (swappable_cache_.get()) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(swappable_cache_.get() ==
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             swappable_cache_->owning_group()->newest_complete_cache());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = true;
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      AssociateCompleteCache(swappable_cache_.get());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_swap_cache_callback_.Run(success, pending_callback_param_);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_swap_cache_callback_.Reset();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_callback_param_ = NULL;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::SetSpawningHostId(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int spawning_process_id, int spawning_host_id) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  spawning_process_id_ = spawning_process_id;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  spawning_host_id_ = spawning_host_id;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const AppCacheHost* AppCacheHost::GetSpawningHost() const {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheBackendImpl* backend = service_->GetBackend(spawning_process_id_);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend ? backend->GetHost(spawning_host_id_) : NULL;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheHost* AppCacheHost::GetParentAppCacheHost() const {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_for_dedicated_worker());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheBackendImpl* backend = service_->GetBackend(parent_process_id_);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return backend ? backend->GetHost(parent_host_id_) : NULL;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheRequestHandler* AppCacheHost::CreateRequestHandler(
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request,
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ResourceType resource_type) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_for_dedicated_worker()) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheHost* parent_host = GetParentAppCacheHost();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (parent_host)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return parent_host->CreateRequestHandler(request, resource_type);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (AppCacheRequestHandler::IsMainResourceType(resource_type)) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Store the first party origin so that it can be used later in SelectCache
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // for checking whether the creation of the appcache is allowed.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    first_party_url_ = request->first_party_for_cookies();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new AppCacheRequestHandler(this, resource_type);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((associated_cache() && associated_cache()->is_complete()) ||
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_selection_pending()) {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new AppCacheRequestHandler(this, resource_type);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::GetResourceList(
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheResourceInfoVector* resource_infos) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (associated_cache_.get() && associated_cache_->is_complete())
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_cache_->ToResourceInfoVector(resource_infos);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)AppCacheStatus AppCacheHost::GetStatus() {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.8 Application cache API
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCache* cache = associated_cache();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache)
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return APPCACHE_STATUS_UNCACHED;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A cache without an owning group represents the cache being constructed
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // during the application cache update process.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache->owning_group())
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return APPCACHE_STATUS_DOWNLOADING;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache->owning_group()->is_obsolete())
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return APPCACHE_STATUS_OBSOLETE;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache->owning_group()->update_status() == AppCacheGroup::CHECKING)
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return APPCACHE_STATUS_CHECKING;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache->owning_group()->update_status() == AppCacheGroup::DOWNLOADING)
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return APPCACHE_STATUS_DOWNLOADING;
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (swappable_cache_.get())
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return APPCACHE_STATUS_UPDATE_READY;
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return APPCACHE_STATUS_IDLE;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::LoadOrCreateGroup(const GURL& manifest_url) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(manifest_url.is_valid());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_selected_manifest_url_ = manifest_url;
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  storage()->LoadOrCreateGroup(manifest_url, this);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::OnGroupLoaded(AppCacheGroup* group,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const GURL& manifest_url) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(manifest_url == pending_selected_manifest_url_);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_selected_manifest_url_ = GURL();
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FinishCacheSelection(NULL, group);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::LoadSelectedCache(int64 cache_id) {
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(cache_id != kAppCacheNoCacheId);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_selected_cache_id_ = cache_id;
3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  storage()->LoadCache(cache_id, this);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::OnCacheLoaded(AppCache* cache, int64 cache_id) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache_id == pending_main_resource_cache_id_) {
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pending_main_resource_cache_id_ = kAppCacheNoCacheId;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    main_resource_cache_ = cache;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (cache_id == pending_selected_cache_id_) {
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    pending_selected_cache_id_ = kAppCacheNoCacheId;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FinishCacheSelection(cache, NULL);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::FinishCacheSelection(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCache *cache, AppCacheGroup* group) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!associated_cache());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.6 The application cache selection algorithm
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If document was loaded from an application cache, Associate document
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // with the application cache from which it was loaded. Invoke the
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // application cache update process for that cache and with the browsing
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // context being navigated.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(cache->owning_group());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(new_master_entry_url_.is_empty());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(cache->owning_group()->manifest_url(), preferred_manifest_url_);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheGroup* owing_group = cache->owning_group();
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* kFormatString =
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Document was loaded from Application Cache with manifest %s";
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frontend_->OnLogMessage(
384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        host_id_, APPCACHE_LOG_INFO,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::StringPrintf(
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            kFormatString, owing_group->manifest_url().spec().c_str()));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AssociateCompleteCache(cache);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!owing_group->is_obsolete() && !owing_group->is_being_deleted()) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      owing_group->StartUpdateWithHost(this);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ObserveGroupBeingUpdated(owing_group);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (group && !group->is_being_deleted()) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If document was loaded using HTTP GET or equivalent, and, there is a
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // manifest URL, and manifest URL has the same origin as document.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Invoke the application cache update process for manifest URL, with
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the browsing context being navigated, and with document and the
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // resource from which document was loaded as the new master resourse.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!group->is_obsolete());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(new_master_entry_url_.is_valid());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(group->manifest_url(), preferred_manifest_url_);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* kFormatString = group->HasCache() ?
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Adding master entry to Application Cache with manifest %s" :
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Creating Application Cache with manifest %s";
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frontend_->OnLogMessage(
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        host_id_, APPCACHE_LOG_INFO,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::StringPrintf(kFormatString,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           group->manifest_url().spec().c_str()));
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The UpdateJob may produce one for us later.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AssociateNoCache(preferred_manifest_url_);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group->StartUpdateWithNewMasterEntry(this, new_master_entry_url_);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ObserveGroupBeingUpdated(group);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, the Document is not associated with any application cache.
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_master_entry_url_ = GURL();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AssociateNoCache(GURL());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond to pending callbacks now that we have a selection.
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_get_status_callback_.is_null())
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoPendingGetStatus();
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (!pending_start_update_callback_.is_null())
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoPendingStartUpdate();
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (!pending_swap_cache_callback_.is_null())
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoPendingSwapCache();
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(Observer, observers_, OnCacheSelectionComplete(this));
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AppCacheHost::OnServiceReinitialized(
4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    AppCacheStorageReference* old_storage_ref) {
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // We continue to use the disabled instance, but arrange for its
4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // deletion when its no longer needed.
4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (old_storage_ref->storage() == storage())
4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    disabled_storage_reference_ = old_storage_ref;
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::ObserveGroupBeingUpdated(AppCacheGroup* group) {
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!group_being_updated_.get());
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group_being_updated_ = group;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  newest_cache_of_group_being_updated_ = group->newest_complete_cache();
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group->AddUpdateObserver(this);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::OnUpdateComplete(AppCacheGroup* group) {
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(group, group_being_updated_.get());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group->RemoveUpdateObserver(this);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a reference to the newest complete cache.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSwappableCache(group);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group_being_updated_ = NULL;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  newest_cache_of_group_being_updated_ = NULL;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (associated_cache_info_pending_ && associated_cache_.get() &&
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      associated_cache_->is_complete()) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheInfo info;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FillCacheInfo(
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        associated_cache_.get(), preferred_manifest_url_, GetStatus(), &info);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_cache_info_pending_ = false;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frontend_->OnCacheSelected(host_id_, info);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::SetSwappableCache(AppCacheGroup* group) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!group) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    swappable_cache_ = NULL;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCache* new_cache = group->newest_complete_cache();
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (new_cache != associated_cache_.get())
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      swappable_cache_ = new_cache;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      swappable_cache_ = NULL;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::LoadMainResourceCache(int64 cache_id) {
477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(cache_id != kAppCacheNoCacheId);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_main_resource_cache_id_ == cache_id ||
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (main_resource_cache_.get() &&
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       main_resource_cache_->cache_id() == cache_id)) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_main_resource_cache_id_ = cache_id;
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  storage()->LoadCache(cache_id, this);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::NotifyMainResourceIsNamespaceEntry(
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& namespace_entry_url) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  main_resource_was_namespace_entry_ = true;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  namespace_entry_url_ = namespace_entry_url;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::NotifyMainResourceBlocked(const GURL& manifest_url) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  main_resource_blocked_ = true;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blocked_manifest_url_ = manifest_url;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppCacheHost::PrepareForTransfer() {
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This can only happen prior to the document having been loaded.
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!associated_cache());
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_selection_pending());
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!group_being_updated_.get());
503f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  host_id_ = kAppCacheNoHostId;
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frontend_ = NULL;
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppCacheHost::CompleteTransfer(int host_id, AppCacheFrontend* frontend) {
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host_id_ = host_id;
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frontend_ = frontend;
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::AssociateNoCache(const GURL& manifest_url) {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // manifest url can be empty.
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AssociateCacheHelper(NULL, manifest_url);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::AssociateIncompleteCache(AppCache* cache,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const GURL& manifest_url) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(cache && !cache->is_complete());
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!manifest_url.is_empty());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AssociateCacheHelper(cache, manifest_url);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::AssociateCompleteCache(AppCache* cache) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(cache && cache->is_complete());
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AssociateCacheHelper(cache, cache->owning_group()->manifest_url());
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheHost::AssociateCacheHelper(AppCache* cache,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const GURL& manifest_url) {
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (associated_cache_.get()) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_cache_->UnassociateHost(this);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  associated_cache_ = cache;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSwappableCache(cache ? cache->owning_group() : NULL);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  associated_cache_info_pending_ = cache && !cache->is_complete();
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheInfo info;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cache)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->AssociateHost(this);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillCacheInfo(cache, manifest_url, GetStatus(), &info);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frontend_->OnCacheSelected(host_id_, info);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
547