18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ApplicationCacheGroup.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OFFLINE_WEB_APPLICATIONS) 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ApplicationCache.h" 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ApplicationCacheHost.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ApplicationCacheResource.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ApplicationCacheStorage.h" 35d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Chrome.h" 36c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu#include "ChromeClient.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentLoader.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DOMApplicationCache.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DOMWindow.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h" 4268513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "FrameLoaderClient.h" 4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InspectorInstrumentation.h" 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MainResourceLoader.h" 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ManifestParser.h" 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h" 47db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "SecurityOrigin.h" 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h" 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/HashMap.h> 50782c335ccf53a3ffc83c9bf7d30c9f5ead1899a8Steve Block#include <wtf/UnusedParam.h> 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INSPECTOR) 53e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "ProgressTracker.h" 54e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 55e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectApplicationCacheGroup::ApplicationCacheGroup(const KURL& manifestURL, bool isCopy) 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : m_manifestURL(manifestURL) 60db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block , m_origin(SecurityOrigin::create(manifestURL)) 61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project , m_updateStatus(Idle) 625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_downloadingPendingMasterResourceLoadersCount(0) 63e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke , m_progressTotal(0) 64e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke , m_progressDone(0) 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_frame(0) 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_storageID(0) 67635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project , m_isObsolete(false) 68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project , m_completionType(None) 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_isCopy(isCopy) 70c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu , m_calledReachedMaxAppCacheSize(false) 71db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block , m_loadedSize(0) 72db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block , m_availableSpaceInQuota(ApplicationCacheStorage::unknownQuota()) 73db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block , m_originQuotaReached(false) 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectApplicationCacheGroup::~ApplicationCacheGroup() 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_isCopy) { 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_newestCache); 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_caches.size() == 1); 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_caches.contains(m_newestCache.get())); 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_cacheBeingUpdated); 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_associatedDocumentLoaders.isEmpty()); 85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_pendingMasterResourceLoaders.isEmpty()); 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_newestCache->group() == this); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_newestCache); 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_caches.isEmpty()); 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stopLoading(); 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project cacheStorage().cacheGroupDestroyed(this); 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectApplicationCache* ApplicationCacheGroup::cacheForMainRequest(const ResourceRequest& request, DocumentLoader*) 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request)) 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch KURL url(request.url()); 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (url.hasFragmentIdentifier()) 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch url.removeFragmentIdentifier(); 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (ApplicationCacheGroup* group = cacheStorage().cacheGroupForURL(url)) { 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(group->newestCache()); 110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!group->isObsolete()); 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return group->newestCache(); 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectApplicationCache* ApplicationCacheGroup::fallbackCacheForMainRequest(const ResourceRequest& request, DocumentLoader*) 119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request)) 121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return 0; 122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch KURL url(request.url()); 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (url.hasFragmentIdentifier()) 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch url.removeFragmentIdentifier(); 1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (ApplicationCacheGroup* group = cacheStorage().fallbackCacheGroupForURL(url)) { 128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(group->newestCache()); 129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!group->isObsolete()); 130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return group->newestCache(); 132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return 0; 135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid ApplicationCacheGroup::selectCache(Frame* frame, const KURL& passedManifestURL) 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(frame && frame->page()); 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!frame->settings()->offlineWebApplicationCacheEnabled()) 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DocumentLoader* documentLoader = frame->loader()->documentLoader(); 1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!documentLoader->applicationCacheHost()->applicationCache()); 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (passedManifestURL.isNull()) { 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project selectCacheWithoutManifestURL(frame); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch KURL manifestURL(passedManifestURL); 1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (manifestURL.hasFragmentIdentifier()) 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch manifestURL.removeFragmentIdentifier(); 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache(); 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (mainResourceCache) { 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (manifestURL == mainResourceCache->group()->m_manifestURL) { 160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The cache may have gotten obsoleted after we've loaded from it, but before we parsed the document and saw cache manifest. 161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (mainResourceCache->group()->isObsolete()) 162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache); 164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project mainResourceCache->group()->update(frame, ApplicationCacheUpdateWithBrowsingContext); 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The main resource was loaded from cache, so the cache must have an entry for it. Mark it as foreign. 167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch KURL resourceURL(documentLoader->responseURL()); 168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (resourceURL.hasFragmentIdentifier()) 169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch resourceURL.removeFragmentIdentifier(); 170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ApplicationCacheResource* resource = mainResourceCache->resourceForURL(resourceURL); 171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool inStorage = resource->storageID(); 172635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project resource->addType(ApplicationCacheResource::Foreign); 173635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (inStorage) 174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheStorage().storeUpdatedType(resource, mainResourceCache); 175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Restart the current navigation from the top of the navigation algorithm, undoing any changes that were made 177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // as part of the initial load. 178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The navigation will not result in the same resource being loaded, because "foreign" entries are never picked during navigation. 179f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch frame->navigationScheduler()->scheduleLocationChange(frame->document()->securityOrigin(), documentLoader->url(), frame->loader()->referrer(), true); 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The resource was loaded from the network, check if it is a HTTP/HTTPS GET. 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const ResourceRequest& request = frame->loader()->activeDocumentLoader()->request(); 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 188635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request)) 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check that the resource URL has the same scheme/host/port as the manifest URL. 192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!protocolHostAndPortAreEqual(manifestURL, request.url())) 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Don't change anything on disk if private browsing is enabled. 1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) { 1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::CHECKING_EVENT, documentLoader); 1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::ERROR_EVENT, documentLoader); 1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL); 203635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch documentLoader->applicationCacheHost()->setCandidateApplicationCacheGroup(group); 205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project group->m_pendingMasterResourceLoaders.add(documentLoader); 2065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian group->m_downloadingPendingMasterResourceLoadersCount++; 207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!group->m_cacheBeingUpdated || group->m_updateStatus != Idle); 209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project group->update(frame, ApplicationCacheUpdateWithBrowsingContext); 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::selectCacheWithoutManifestURL(Frame* frame) 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!frame->settings()->offlineWebApplicationCacheEnabled()) 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DocumentLoader* documentLoader = frame->loader()->documentLoader(); 2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!documentLoader->applicationCacheHost()->applicationCache()); 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ApplicationCache* mainResourceCache = documentLoader->applicationCacheHost()->mainResourceApplicationCache(); 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (mainResourceCache) { 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project mainResourceCache->group()->associateDocumentLoaderWithCache(documentLoader, mainResourceCache); 224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project mainResourceCache->group()->update(frame, ApplicationCacheUpdateWithBrowsingContext); 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader) 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_pendingMasterResourceLoaders.contains(loader)); 231635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_completionType == None || m_pendingEntries.isEmpty()); 2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch KURL url = loader->url(); 2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (url.hasFragmentIdentifier()) 2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch url.removeFragmentIdentifier(); 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project switch (m_completionType) { 237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case None: 238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The main resource finished loading before the manifest was ready. It will be handled via dispatchMainResources() later. 239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case NoUpdate: 241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); 242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project associateDocumentLoaderWithCache(loader, m_newestCache.get()); 243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (ApplicationCacheResource* resource = m_newestCache->resourceForURL(url)) { 2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!(resource->type() & ApplicationCacheResource::Master)) { 2468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian resource->addType(ApplicationCacheResource::Master); 247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!resource->storageID()); 248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else 2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_newestCache->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, loader->mainResourceData())); 251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case Failure: 254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache update has been a failure, so there is no reason to keep the document associated with the incomplete cache 255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // (its main resource was not cached yet, so it is likely that the application changed significantly server-side). 256635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading(). 2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too. 258635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_associatedDocumentLoaders.remove(loader); 2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); 260635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case Completed: 262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_associatedDocumentLoaders.contains(loader)); 263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) { 2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!(resource->type() & ApplicationCacheResource::Master)) { 2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian resource->addType(ApplicationCacheResource::Master); 267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!resource->storageID()); 268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else 2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, loader->mainResourceData())); 271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The "cached" event will be posted to all associated documents once update is complete. 272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_downloadingPendingMasterResourceLoadersCount--; 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project checkIfLoadIsComplete(); 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::failedLoadingMainResource(DocumentLoader* loader) 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_pendingMasterResourceLoaders.contains(loader)); 282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_completionType == None || m_pendingEntries.isEmpty()); 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project switch (m_completionType) { 285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case None: 286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The main resource finished loading before the manifest was ready. It will be handled via dispatchMainResources() later. 287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case NoUpdate: 289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); 290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The manifest didn't change, and we have a relevant cache - but the main resource download failed mid-way, so it cannot be stored to the cache, 292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // and the loader does not get associated to it. If there are other main resources being downloaded for this cache group, they may still succeed. 2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); 294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case Failure: 297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache update failed, too. 298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); // Already cleared out by stopLoading(). 2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!loader->applicationCacheHost()->applicationCache() || loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated); 300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch loader->applicationCacheHost()->setApplicationCache(0); // Will unset candidate, too. 302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_associatedDocumentLoaders.remove(loader); 3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); 304635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 305635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case Completed: 306635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // The cache manifest didn't list this main resource, and all cache entries were already updated successfully - but the main resource failed to load, 307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // so it cannot be stored to the cache. If there are other main resources being downloaded for this cache group, they may still succeed. 308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_associatedDocumentLoaders.contains(loader)); 3090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(loader->applicationCacheHost()->applicationCache() == m_cacheBeingUpdated); 3100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!loader->applicationCacheHost()->candidateApplicationCacheGroup()); 311635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_associatedDocumentLoaders.remove(loader); 3120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch loader->applicationCacheHost()->setApplicationCache(0); 313635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::ERROR_EVENT, loader); 315635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 316635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 317635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 318635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_downloadingPendingMasterResourceLoadersCount--; 320635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project checkIfLoadIsComplete(); 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::stopLoading() 324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_manifestHandle) { 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_currentHandle); 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_manifestHandle->setClient(0); 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_manifestHandle->cancel(); 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_manifestHandle = 0; 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_currentHandle) { 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_manifestHandle); 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_cacheBeingUpdated); 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentHandle->setClient(0); 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentHandle->cancel(); 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentHandle = 0; 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_cacheBeingUpdated = 0; 343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_pendingEntries.clear(); 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 346635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ApplicationCacheGroup::disassociateDocumentLoader(DocumentLoader* loader) 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<DocumentLoader*>::iterator it = m_associatedDocumentLoaders.find(loader); 349635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (it != m_associatedDocumentLoaders.end()) 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_associatedDocumentLoaders.remove(it); 351635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_pendingMasterResourceLoaders.remove(loader); 353635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch loader->applicationCacheHost()->setApplicationCache(0); // Will set candidate to 0, too. 355635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 356635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_associatedDocumentLoaders.isEmpty() || !m_pendingMasterResourceLoaders.isEmpty()) 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 358635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_caches.isEmpty()) { 360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // There is an initial cache attempt in progress. 361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_newestCache); 362635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Delete ourselves, causing the cache attempt to be stopped. 363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project delete this; 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 366635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 367635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_caches.contains(m_newestCache.get())); 368635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 369635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Release our reference to the newest cache. This could cause us to be deleted. 370635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Any ongoing updates will be stopped from destructor. 371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_newestCache.release(); 372635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::cacheDestroyed(ApplicationCache* cache) 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 376635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_caches.contains(cache)) 377635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_caches.remove(cache); 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 381635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_caches.isEmpty()) { 382635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_associatedDocumentLoaders.isEmpty()); 383635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_pendingMasterResourceLoaders.isEmpty()); 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete this; 385635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid ApplicationCacheGroup::stopLoadingInFrame(Frame* frame) 389a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 390a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (frame != m_frame) 391a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 392a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 393a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch stopLoading(); 394a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 395a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::setNewestCache(PassRefPtr<ApplicationCache> newestCache) 397635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 398635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_newestCache = newestCache; 399635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_caches.add(m_newestCache.get()); 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_newestCache->setGroup(this); 40265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentation::updateApplicationCacheStatus(m_frame); 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 405635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ApplicationCacheGroup::makeObsolete() 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 407635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (isObsolete()) 408635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 409635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 410635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_isObsolete = true; 411635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheStorage().cacheGroupMadeObsolete(this); 412635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_storageID); 41365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentation::updateApplicationCacheStatus(m_frame); 414635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 415635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 416635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption updateOption) 417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 418635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_updateStatus == Checking || m_updateStatus == Downloading) { 419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (updateOption == ApplicationCacheUpdateWithBrowsingContext) { 4200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader()->documentLoader()); 421635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_updateStatus == Downloading) 4220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, frame->loader()->documentLoader()); 423635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 425635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Don't change anything on disk if private browsing is enabled. 4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) { 4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(m_pendingMasterResourceLoaders.isEmpty()); 4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(m_pendingEntries.isEmpty()); 4318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(!m_cacheBeingUpdated); 4320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader()->documentLoader()); 4330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::NOUPDATE_EVENT, frame->loader()->documentLoader()); 4348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 4358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_frame); 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_frame = frame; 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 440e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke setUpdateStatus(Checking); 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::CHECKING_EVENT, m_associatedDocumentLoaders); 443635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_newestCache) { 444635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(updateOption == ApplicationCacheUpdateWithBrowsingContext); 4450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::CHECKING_EVENT, frame->loader()->documentLoader()); 446635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_manifestHandle); 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_manifestResource); 450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_completionType == None); 451635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Handle defer loading 4538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_manifestHandle = createResourceHandle(m_manifestURL, m_newestCache ? m_newestCache->manifestResource() : 0); 4548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 4558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianPassRefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const KURL& url, ApplicationCacheResource* newestCachedResource) 4578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 4588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ResourceRequest request(url); 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_frame->loader()->applyUserAgent(request); 4608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian request.setHTTPHeaderField("Cache-Control", "max-age=0"); 4618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (newestCachedResource) { 4638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian const String& lastModified = newestCachedResource->response().httpHeaderField("Last-Modified"); 4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian const String& eTag = newestCachedResource->response().httpHeaderField("ETag"); 4658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!lastModified.isEmpty() || !eTag.isEmpty()) { 4668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!lastModified.isEmpty()) 4678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian request.setHTTPHeaderField("If-Modified-Since", lastModified); 4688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!eTag.isEmpty()) 4698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian request.setHTTPHeaderField("If-None-Match", eTag); 4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 472e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 47368513a70bcd92384395513322f1b801e7bf9c729Steve Block RefPtr<ResourceHandle> handle = ResourceHandle::create(m_frame->loader()->networkingContext(), request, this, false, true); 474e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INSPECTOR) 475e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // Because willSendRequest only gets called during redirects, we initialize 476e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // the identifier and the first willSendRequest here. 477e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_currentResourceIdentifier = m_frame->page()->progress()->createUniqueIdentifier(); 47865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ResourceResponse redirectResponse = ResourceResponse(); 4792bde8e466a4451c7319e3a072d118917957d6554Steve Block InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, m_frame->loader()->documentLoader(), request, redirectResponse); 480e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 481e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return handle; 482e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 483e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response) 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 486e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INSPECTOR) 48765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch DocumentLoader* loader = (handle == m_manifestHandle) ? 0 : m_frame->loader()->documentLoader(); 48865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(m_frame, m_currentResourceIdentifier, response); 48965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentation::didReceiveResourceResponse(cookie, m_currentResourceIdentifier, loader, response); 490e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 491e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (handle == m_manifestHandle) { 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project didReceiveManifestResponse(response); 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(handle == m_currentHandle); 498635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 499967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch KURL url(handle->firstRequest().url()); 5000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (url.hasFragmentIdentifier()) 5010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch url.removeFragmentIdentifier(); 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_currentResource); 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_pendingEntries.contains(url)); 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned type = m_pendingEntries.get(url); 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If this is an initial cache attempt, we should not get master resources delivered here. 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_newestCache) 5108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(!(type & ApplicationCacheResource::Master)); 5118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m_newestCache && response.httpStatusCode() == 304) { // Not modified. 5130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url); 5148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (newestCachedResource) { 5152bde8e466a4451c7319e3a072d118917957d6554Steve Block m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path())); 516967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_pendingEntries.remove(m_currentHandle->firstRequest().url()); 5178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_currentHandle->cancel(); 5188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_currentHandle = 0; 5198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Load the next resource, if any. 5208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian startLoadingEntry(); 5218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 5228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 5238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The server could return 304 for an unconditional request - in this case, we handle the response as a normal error. 5248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 525635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 526967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (response.httpStatusCode() / 100 != 2 || response.url() != m_currentHandle->firstRequest().url()) { 527635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) { 528635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Note that cacheUpdateFailed() can cause the cache group to be deleted. 529635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheUpdateFailed(); 530635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) { 531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Skip this resource. It is dropped from the cache. 532635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_currentHandle->cancel(); 533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_currentHandle = 0; 5340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_pendingEntries.remove(url); 535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Load the next resource, if any. 536635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project startLoadingEntry(); 537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else { 538635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act 539635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // as if that was the fetched resource, ignoring the resource obtained from the network. 540635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_newestCache); 541967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->firstRequest().url()); 5428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(newestCachedResource); 5432bde8e466a4451c7319e3a072d118917957d6554Steve Block m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path())); 544967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_pendingEntries.remove(m_currentHandle->firstRequest().url()); 545635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_currentHandle->cancel(); 546635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_currentHandle = 0; 5478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Load the next resource, if any. 548635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project startLoadingEntry(); 549635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 550635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 551635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentResource = ApplicationCacheResource::create(url, response, type); 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid ApplicationCacheGroup::didReceiveData(ResourceHandle* handle, const char* data, int length, int encodedDataLength) 5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch UNUSED_PARAM(encodedDataLength); 5592bde8e466a4451c7319e3a072d118917957d6554Steve Block 560e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INSPECTOR) 5612bde8e466a4451c7319e3a072d118917957d6554Steve Block InspectorInstrumentation::didReceiveContentLength(m_frame, m_currentResourceIdentifier, length, 0); 562e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 563e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (handle == m_manifestHandle) { 5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project didReceiveManifestData(data, length); 5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(handle == m_currentHandle); 5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_currentResource); 5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentResource->data()->append(data, length); 573db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 574db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_loadedSize += length; 5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 57768513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle, double finishTime) 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 579e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INSPECTOR) 58065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentation::didFinishLoading(m_frame, m_currentResourceIdentifier, finishTime); 581e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 582e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (handle == m_manifestHandle) { 5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project didFinishLoadingManifest(); 5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 587db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 588db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // After finishing the loading of any resource, we check if it will 589db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // fit in our last known quota limit. 590db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (m_availableSpaceInQuota == ApplicationCacheStorage::unknownQuota()) { 591db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Failed to determine what is left in the quota. Fallback to allowing anything. 592db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (!cacheStorage().remainingSizeForOriginExcludingCache(m_origin.get(), m_newestCache.get(), m_availableSpaceInQuota)) 593db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_availableSpaceInQuota = ApplicationCacheStorage::noQuota(); 594db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block } 595db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 596db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Check each resource, as it loads, to see if it would fit in our 597db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // idea of the available quota space. 598db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (m_availableSpaceInQuota < m_loadedSize) { 599db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_currentResource = 0; 600db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block cacheUpdateFailedDueToOriginQuota(); 601db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block return; 602db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block } 603db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_currentHandle == handle); 605967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ASSERT(m_pendingEntries.contains(handle->firstRequest().url())); 6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 607967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_pendingEntries.remove(handle->firstRequest().url()); 6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_cacheBeingUpdated); 6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_cacheBeingUpdated->addResource(m_currentResource.release()); 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentHandle = 0; 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 614635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Load the next resource, if any. 615635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project startLoadingEntry(); 6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 618e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError& error) 6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 620e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INSPECTOR) 62165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentation::didFailLoading(m_frame, m_currentResourceIdentifier, error); 622e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 623e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (handle == m_manifestHandle) { 625635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheUpdateFailed(); 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 628635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 629967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch unsigned type = m_currentResource ? m_currentResource->type() : m_pendingEntries.get(handle->firstRequest().url()); 630967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch KURL url(handle->firstRequest().url()); 6310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (url.hasFragmentIdentifier()) 6320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch url.removeFragmentIdentifier(); 633635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 6348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(!m_currentResource || !m_pendingEntries.contains(url)); 635635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_currentResource = 0; 6368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_pendingEntries.remove(url); 637635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 638635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) { 639635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Note that cacheUpdateFailed() can cause the cache group to be deleted. 640635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheUpdateFailed(); 641635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else { 642635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act 643635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // as if that was the fetched resource, ignoring the resource obtained from the network. 644635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_newestCache); 6458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url); 6468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(newestCachedResource); 6472bde8e466a4451c7319e3a072d118917957d6554Steve Block m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data(), newestCachedResource->path())); 648635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Load the next resource, if any. 649635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project startLoadingEntry(); 650635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& response) 6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 655635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_manifestResource); 656635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_manifestHandle); 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 658635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) { 659635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project manifestNotFound(); 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 662635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 6638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (response.httpStatusCode() == 304) 6648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 6658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 666967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (response.httpStatusCode() / 100 != 2 || response.url() != m_manifestHandle->firstRequest().url() || !equalIgnoringCase(response.mimeType(), "text/cache-manifest")) { 667635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheUpdateFailed(); 668635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 669635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 670635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 671967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_manifestResource = ApplicationCacheResource::create(m_manifestHandle->firstRequest().url(), response, ApplicationCacheResource::Manifest); 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::didReceiveManifestData(const char* data, int length) 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m_manifestResource) 6778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_manifestResource->data()->append(data, length); 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::didFinishLoadingManifest() 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isUpgradeAttempt = m_newestCache; 6838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!isUpgradeAttempt && !m_manifestResource) { 6858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The server returned 304 Not Modified even though we didn't send a conditional request. 686635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheUpdateFailed(); 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_manifestHandle = 0; 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Check if the manifest was not modified. 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isUpgradeAttempt) { 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ApplicationCacheResource* newestManifest = m_newestCache->manifestResource(); 6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(newestManifest); 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified. 698643ca7872b450ea4efacab6188849e5aac2ba161Steve Block (newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size()))) { 699635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 700635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_completionType = NoUpdate; 7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_manifestResource = 0; 702635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project deliverDelayedMainResources(); 703635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Manifest manifest; 7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!parseManifest(m_manifestURL, m_manifestResource->data()->data(), m_manifestResource->data()->size(), manifest)) { 710635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cacheUpdateFailed(); 7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 713635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 714635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); 715635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_cacheBeingUpdated = ApplicationCache::create(); 716635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_cacheBeingUpdated->setGroup(this); 717635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 718635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HashSet<DocumentLoader*>::const_iterator masterEnd = m_pendingMasterResourceLoaders.end(); 719635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (HashSet<DocumentLoader*>::const_iterator iter = m_pendingMasterResourceLoaders.begin(); iter != masterEnd; ++iter) 720635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project associateDocumentLoaderWithCache(*iter, m_cacheBeingUpdated.get()); 721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We have the manifest, now download the resources. 723e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke setUpdateStatus(Downloading); 7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::DOWNLOADING_EVENT, m_associatedDocumentLoaders); 726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 727635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_pendingEntries.isEmpty()); 7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isUpgradeAttempt) { 7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ApplicationCache::ResourceMap::const_iterator end = m_newestCache->end(); 7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (ApplicationCache::ResourceMap::const_iterator it = m_newestCache->begin(); it != end; ++it) { 7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned type = it->second->type(); 7330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (type & ApplicationCacheResource::Master) 7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project addEntry(it->first, type); 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<String>::const_iterator end = manifest.explicitURLs.end(); 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (HashSet<String>::const_iterator it = manifest.explicitURLs.begin(); it != end; ++it) 7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project addEntry(*it, ApplicationCacheResource::Explicit); 741635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 742635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project size_t fallbackCount = manifest.fallbackURLs.size(); 743635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (size_t i = 0; i < fallbackCount; ++i) 744635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project addEntry(manifest.fallbackURLs[i].second, ApplicationCacheResource::Fallback); 7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_cacheBeingUpdated->setOnlineWhitelist(manifest.onlineWhitelistedURLs); 747635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_cacheBeingUpdated->setFallbackURLs(manifest.fallbackURLs); 748231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_cacheBeingUpdated->setAllowsAllNetworkRequests(manifest.allowAllNetworkRequests); 749e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 750e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_progressTotal = m_pendingEntries.size(); 751e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_progressDone = 0; 752e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project startLoadingEntry(); 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 756c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescuvoid ApplicationCacheGroup::didReachMaxAppCacheSize() 757c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu{ 758c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu ASSERT(m_frame); 759c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu ASSERT(m_cacheBeingUpdated); 760c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu m_frame->page()->chrome()->client()->reachedMaxAppCacheSize(cacheStorage().spaceNeeded(m_cacheBeingUpdated->estimatedSizeInStorage())); 761c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu m_calledReachedMaxAppCacheSize = true; 762c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu checkIfLoadIsComplete(); 763c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu} 764c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu 765db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid ApplicationCacheGroup::didReachOriginQuota(PassRefPtr<Frame> frame) 766db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{ 767db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Inform the client the origin quota has been reached, 768db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // they may decide to increase the quota. 769db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block frame->page()->chrome()->client()->reachedApplicationCacheOriginQuota(m_origin.get()); 770db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block} 771db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::cacheUpdateFailed() 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stopLoading(); 775635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_manifestResource = 0; 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 777635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Wait for master resource loads to finish. 778635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_completionType = Failure; 779635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project deliverDelayedMainResources(); 780635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 781db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 782db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid ApplicationCacheGroup::cacheUpdateFailedDueToOriginQuota() 783db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{ 784db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (!m_originQuotaReached) { 785db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_originQuotaReached = true; 786db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block scheduleReachedOriginQuotaCallback(); 787db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block } 788db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 789db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block cacheUpdateFailed(); 790db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block} 791635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 792635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ApplicationCacheGroup::manifestNotFound() 793635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 794635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project makeObsolete(); 795635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 7960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::OBSOLETE_EVENT, m_associatedDocumentLoaders); 7970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_pendingMasterResourceLoaders); 798635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 799635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project stopLoading(); 800635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 801635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_pendingEntries.isEmpty()); 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_manifestResource = 0; 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 804635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (!m_pendingMasterResourceLoaders.isEmpty()) { 805635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HashSet<DocumentLoader*>::iterator it = m_pendingMasterResourceLoaders.begin(); 8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT((*it)->applicationCacheHost()->candidateApplicationCacheGroup() == this); 8080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!(*it)->applicationCacheHost()->applicationCache()); 8090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch (*it)->applicationCacheHost()->setCandidateApplicationCacheGroup(0); 810635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_pendingMasterResourceLoaders.remove(it); 8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 812635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 8135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_downloadingPendingMasterResourceLoadersCount = 0; 814e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke setUpdateStatus(Idle); 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_frame = 0; 8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 817635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_caches.isEmpty()) { 818635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_associatedDocumentLoaders.isEmpty()); 819635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete this; 821635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::checkIfLoadIsComplete() 8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_manifestHandle || !m_pendingEntries.isEmpty() || m_downloadingPendingMasterResourceLoadersCount) 8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 829635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // We're done, all resources have finished downloading (successfully or not). 830635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool isUpgradeAttempt = m_newestCache; 8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 833635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project switch (m_completionType) { 834635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case None: 835635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT_NOT_REACHED(); 836635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 837635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case NoUpdate: 838635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(isUpgradeAttempt); 839635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); 8408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 8418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The storage could have been manually emptied by the user. 8428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!m_storageID) 8438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian cacheStorage().storeNewestCache(this); 8448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 8450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::NOUPDATE_EVENT, m_associatedDocumentLoaders); 846635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 847635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case Failure: 848635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_cacheBeingUpdated); 8490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders); 850635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_caches.isEmpty()) { 851635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_associatedDocumentLoaders.isEmpty()); 852635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project delete this; 853635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 855635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 856635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project case Completed: { 857635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // FIXME: Fetch the resource from manifest URL again, and check whether it is identical to the one used for update (in case the application was upgraded server-side in the meanwhile). (<rdar://problem/6467625>) 858635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 859635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_cacheBeingUpdated); 860c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu if (m_manifestResource) 861c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu m_cacheBeingUpdated->setManifestResource(m_manifestResource.release()); 862c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu else { 863c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // We can get here as a result of retrying the Complete step, following 864c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // a failure of the cache storage to save the newest cache due to hitting 865c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // the maximum size. In such a case, m_manifestResource may be 0, as 866c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // the manifest was already set on the newest cache object. 867c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu ASSERT(cacheStorage().isMaximumSizeReached() && m_calledReachedMaxAppCacheSize); 868c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu } 869635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 870db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block ApplicationCacheStorage::FailureReason failureReason; 8712bde8e466a4451c7319e3a072d118917957d6554Steve Block RefPtr<ApplicationCache> oldNewestCache = (m_newestCache == m_cacheBeingUpdated) ? RefPtr<ApplicationCache>() : m_newestCache; 872635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project setNewestCache(m_cacheBeingUpdated.release()); 873db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (cacheStorage().storeNewestCache(this, oldNewestCache.get(), failureReason)) { 8740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // New cache stored, now remove the old cache. 8750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (oldNewestCache) 8760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch cacheStorage().remove(oldNewestCache.get()); 877e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 878e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // Fire the final progress event. 879e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ASSERT(m_progressDone == m_progressTotal); 880e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke postListenerTask(ApplicationCacheHost::PROGRESS_EVENT, m_progressTotal, m_progressDone, m_associatedDocumentLoaders); 881e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 882e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // Fire the success event. 8830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch postListenerTask(isUpgradeAttempt ? ApplicationCacheHost::UPDATEREADY_EVENT : ApplicationCacheHost::CACHED_EVENT, m_associatedDocumentLoaders); 884db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // It is clear that the origin quota was not reached, so clear the flag if it was set. 885db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_originQuotaReached = false; 8860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } else { 887db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (failureReason == ApplicationCacheStorage::OriginQuotaReached) { 888db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // We ran out of space for this origin. Roll back to previous state. 889db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (oldNewestCache) 890db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block setNewestCache(oldNewestCache.release()); 891db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block cacheUpdateFailedDueToOriginQuota(); 892db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block return; 893db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block } 894db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 895db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (failureReason == ApplicationCacheStorage::TotalQuotaReached && !m_calledReachedMaxAppCacheSize) { 8960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // We ran out of space. All the changes in the cache storage have 8970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // been rolled back. We roll back to the previous state in here, 8980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // as well, call the chrome client asynchronously and retry to 8990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // save the new cache. 9000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 9010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Save a reference to the new cache. 9020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_cacheBeingUpdated = m_newestCache.release(); 9030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (oldNewestCache) { 9040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Reinstate the oldNewestCache. 9050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch setNewestCache(oldNewestCache.release()); 9060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 9070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch scheduleReachedMaxAppCacheSizeCallback(); 9080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 909db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block } 910db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 911db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Run the "cache failure steps" 912db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Fire the error events to all pending master entries, as well any other cache hosts 913db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // currently associated with a cache in this group. 914db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block postListenerTask(ApplicationCacheHost::ERROR_EVENT, m_associatedDocumentLoaders); 915db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Disassociate the pending master entries from the failed new cache. Note that 916db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // all other loaders in the m_associatedDocumentLoaders are still associated with 917db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // some other cache in this group. They are not associated with the failed new cache. 918db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 919db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Need to copy loaders, because the cache group may be destroyed at the end of iteration. 920db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block Vector<DocumentLoader*> loaders; 921db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block copyToVector(m_pendingMasterResourceLoaders, loaders); 922db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block size_t count = loaders.size(); 923db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block for (size_t i = 0; i != count; ++i) 924db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block disassociateDocumentLoader(loaders[i]); // This can delete this group. 925db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 926db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Reinstate the oldNewestCache, if there was one. 927db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (oldNewestCache) { 928db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // This will discard the failed new cache. 929db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block setNewestCache(oldNewestCache.release()); 9300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } else { 931db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // We must have been deleted by the last call to disassociateDocumentLoader(). 932db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block return; 9330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 9340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 935635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 937635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 938635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 9395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Empty cache group's list of pending master entries. 9405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_pendingMasterResourceLoaders.clear(); 941635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_completionType = None; 942e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke setUpdateStatus(Idle); 943635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_frame = 0; 944db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_loadedSize = 0; 945db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_availableSpaceInQuota = ApplicationCacheStorage::unknownQuota(); 946c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu m_calledReachedMaxAppCacheSize = false; 9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::startLoadingEntry() 9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_cacheBeingUpdated); 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_pendingEntries.isEmpty()) { 954635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_completionType = Completed; 955635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project deliverDelayedMainResources(); 9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EntryMap::const_iterator it = m_pendingEntries.begin(); 9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 961e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke postListenerTask(ApplicationCacheHost::PROGRESS_EVENT, m_progressTotal, m_progressDone, m_associatedDocumentLoaders); 962e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_progressDone++; 9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_currentHandle); 9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 966231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_currentHandle = createResourceHandle(KURL(ParsedURLString, it->first), m_newestCache ? m_newestCache->resourceForURL(it->first) : 0); 9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 969635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ApplicationCacheGroup::deliverDelayedMainResources() 970635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 971635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Need to copy loaders, because the cache group may be destroyed at the end of iteration. 972635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Vector<DocumentLoader*> loaders; 973635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project copyToVector(m_pendingMasterResourceLoaders, loaders); 974635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project size_t count = loaders.size(); 975635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (size_t i = 0; i != count; ++i) { 976635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DocumentLoader* loader = loaders[i]; 977635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (loader->isLoadingMainResource()) 978635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project continue; 979635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 980635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const ResourceError& error = loader->mainDocumentError(); 981635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (error.isNull()) 982635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project finishedLoadingMainResource(loader); 983635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else 984635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project failedLoadingMainResource(loader); 985635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 986635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!count) 987635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project checkIfLoadIsComplete(); 988635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 989635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::addEntry(const String& url, unsigned type) 9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_cacheBeingUpdated); 993231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(!KURL(ParsedURLString, url).hasFragmentIdentifier()); 9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Don't add the URL if we already have an master resource in the cache 996635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // (i.e., the main resource finished loading before the manifest). 9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) { 9988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(resource->type() & ApplicationCacheResource::Master); 999635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_frame->loader()->documentLoader()->isLoadingMainResource()); 10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resource->addType(type); 10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Don't add the URL if it's the same as the manifest URL. 1006635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(m_manifestResource); 1007635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_manifestResource->url() == url) { 10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_manifestResource->addType(type); 10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pair<EntryMap::iterator, bool> result = m_pendingEntries.add(url, type); 10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result.second) 10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result.first->second |= type; 10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::associateDocumentLoaderWithCache(DocumentLoader* loader, ApplicationCache* cache) 10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1020635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // If teardown started already, revive the group. 1021635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_newestCache && !m_cacheBeingUpdated) 1022635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_newestCache = cache; 1023635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1024635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!m_isObsolete); 1025635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 10260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch loader->applicationCacheHost()->setApplicationCache(cache); 1027635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_associatedDocumentLoaders.contains(loader)); 10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_associatedDocumentLoaders.add(loader); 10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1031c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu 1032c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescuclass ChromeClientCallbackTimer: public TimerBase { 1033c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescupublic: 1034c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu ChromeClientCallbackTimer(ApplicationCacheGroup* cacheGroup) 1035c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu : m_cacheGroup(cacheGroup) 1036c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu { 1037c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu } 1038c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu 1039c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescuprivate: 1040c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu virtual void fired() 1041c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu { 1042c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu m_cacheGroup->didReachMaxAppCacheSize(); 1043c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu delete this; 1044c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu } 1045c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // Note that there is no need to use a RefPtr here. The ApplicationCacheGroup instance is guaranteed 1046c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // to be alive when the timer fires since invoking the ChromeClient callback is part of its normal 1047c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // update machinery and nothing can yet cause it to get deleted. 1048c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu ApplicationCacheGroup* m_cacheGroup; 1049c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu}; 1050c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu 1051c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescuvoid ApplicationCacheGroup::scheduleReachedMaxAppCacheSizeCallback() 1052c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu{ 1053c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu ASSERT(isMainThread()); 1054c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu ChromeClientCallbackTimer* timer = new ChromeClientCallbackTimer(this); 1055c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu timer->startOneShot(0); 1056c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu // The timer will delete itself once it fires. 1057c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu} 1058c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu 1059db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid ApplicationCacheGroup::scheduleReachedOriginQuotaCallback() 1060db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{ 1061dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch // FIXME: it might be nice to run this asynchronously, because there is no return value to wait for. 1062dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch didReachOriginQuota(m_frame); 1063db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block} 1064db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 1065635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectclass CallCacheListenerTask : public ScriptExecutionContext::Task { 1066635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectpublic: 1067e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke static PassOwnPtr<CallCacheListenerTask> create(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone) 1068635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project { 1069e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return adoptPtr(new CallCacheListenerTask(loader, eventID, progressTotal, progressDone)); 1070635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1072635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project virtual void performTask(ScriptExecutionContext* context) 1073635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project { 10740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 10750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT_UNUSED(context, context->isDocument()); 10760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Frame* frame = m_documentLoader->frame(); 10770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!frame) 10780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 10790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 10800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(frame->loader()->documentLoader() == m_documentLoader.get()); 10810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1082e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_documentLoader->applicationCacheHost()->notifyDOMApplicationCache(m_eventID, m_progressTotal, m_progressDone); 1083635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 1084635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1085635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectprivate: 1086e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke CallCacheListenerTask(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone) 10870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch : m_documentLoader(loader) 10880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_eventID(eventID) 1089e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke , m_progressTotal(progressTotal) 1090e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke , m_progressDone(progressDone) 1091635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project { 1092635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 1093635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 10940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RefPtr<DocumentLoader> m_documentLoader; 10950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ApplicationCacheHost::EventID m_eventID; 1096e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int m_progressTotal; 1097e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int m_progressDone; 1098635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}; 1099635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1100e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid ApplicationCacheGroup::postListenerTask(ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone, const HashSet<DocumentLoader*>& loaderSet) 1101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 1102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HashSet<DocumentLoader*>::const_iterator loaderSetEnd = loaderSet.end(); 1103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (HashSet<DocumentLoader*>::const_iterator iter = loaderSet.begin(); iter != loaderSetEnd; ++iter) 1104e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke postListenerTask(eventID, progressTotal, progressDone, *iter); 11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1107e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid ApplicationCacheGroup::postListenerTask(ApplicationCacheHost::EventID eventID, int progressTotal, int progressDone, DocumentLoader* loader) 11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Frame* frame = loader->frame(); 1110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!frame) 1111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 1112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1113635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(frame->loader()->documentLoader() == loader); 1114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1115e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke frame->document()->postTask(CallCacheListenerTask::create(loader, eventID, progressTotal, progressDone)); 1116e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 1117e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1118e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid ApplicationCacheGroup::setUpdateStatus(UpdateStatus status) 1119e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 1120e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_updateStatus = status; 112165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch InspectorInstrumentation::updateApplicationCacheStatus(m_frame); 11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ApplicationCacheGroup::clearStorageID() 11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_storageID = 0; 11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<ApplicationCache*>::const_iterator end = m_caches.end(); 11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (HashSet<ApplicationCache*>::const_iterator it = m_caches.begin(); it != end; ++it) 11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (*it)->clearStorageID(); 11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1132c60802dd50f86c37e0596d41c3ef6fc2c8804da4Andrei Popescu 11338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // ENABLE(OFFLINE_WEB_APPLICATIONS) 1137