1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/uriloader/prefetch/OfflineCacheUpdateGlue.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,208 @@ 1.4 +/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "OfflineCacheUpdateGlue.h" 1.10 +#include "nsOfflineCacheUpdate.h" 1.11 +#include "mozilla/Services.h" 1.12 + 1.13 +#include "nsIApplicationCache.h" 1.14 +#include "nsIApplicationCacheChannel.h" 1.15 +#include "nsIApplicationCacheContainer.h" 1.16 +#include "nsIChannel.h" 1.17 +#include "nsIDocument.h" 1.18 +#include "prlog.h" 1.19 + 1.20 +#if defined(PR_LOGGING) 1.21 +// 1.22 +// To enable logging (see prlog.h for full details): 1.23 +// 1.24 +// set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5 1.25 +// set NSPR_LOG_FILE=offlineupdate.log 1.26 +// 1.27 +// this enables PR_LOG_ALWAYS level information and places all output in 1.28 +// the file offlineupdate.log 1.29 +// 1.30 +extern PRLogModuleInfo *gOfflineCacheUpdateLog; 1.31 +#endif 1.32 + 1.33 +#undef LOG 1.34 +#define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args) 1.35 + 1.36 +#undef LOG_ENABLED 1.37 +#define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4) 1.38 + 1.39 +namespace mozilla { 1.40 +namespace docshell { 1.41 + 1.42 +//----------------------------------------------------------------------------- 1.43 +// OfflineCacheUpdateGlue::nsISupports 1.44 +//----------------------------------------------------------------------------- 1.45 + 1.46 +NS_IMPL_ISUPPORTS(OfflineCacheUpdateGlue, 1.47 + nsIOfflineCacheUpdate, 1.48 + nsIOfflineCacheUpdateObserver, 1.49 + nsISupportsWeakReference) 1.50 + 1.51 +//----------------------------------------------------------------------------- 1.52 +// OfflineCacheUpdateGlue <public> 1.53 +//----------------------------------------------------------------------------- 1.54 + 1.55 +OfflineCacheUpdateGlue::OfflineCacheUpdateGlue() 1.56 +{ 1.57 + LOG(("OfflineCacheUpdateGlue::OfflineCacheUpdateGlue [%p]", this)); 1.58 +} 1.59 + 1.60 +OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue() 1.61 +{ 1.62 + LOG(("OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue [%p]", this)); 1.63 +} 1.64 + 1.65 +nsIOfflineCacheUpdate* 1.66 +OfflineCacheUpdateGlue::EnsureUpdate() 1.67 +{ 1.68 + if (!mUpdate) { 1.69 + mUpdate = new nsOfflineCacheUpdate(); 1.70 + LOG(("OfflineCacheUpdateGlue [%p] is using update [%p]", this, mUpdate.get())); 1.71 + } 1.72 + 1.73 + return mUpdate; 1.74 +} 1.75 + 1.76 +NS_IMETHODIMP 1.77 +OfflineCacheUpdateGlue::Schedule() 1.78 +{ 1.79 + nsCOMPtr<nsIObserverService> observerService = 1.80 + mozilla::services::GetObserverService(); 1.81 + if (observerService) { 1.82 + LOG(("Calling offline-cache-update-added")); 1.83 + observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this), 1.84 + "offline-cache-update-added", 1.85 + nullptr); 1.86 + LOG(("Done offline-cache-update-added")); 1.87 + } 1.88 + 1.89 + if (!EnsureUpdate()) 1.90 + return NS_ERROR_NULL_POINTER; 1.91 + 1.92 + // Do not use weak reference, we must survive! 1.93 + mUpdate->AddObserver(this, false); 1.94 + 1.95 + return mUpdate->Schedule(); 1.96 +} 1.97 + 1.98 +NS_IMETHODIMP 1.99 +OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI, 1.100 + nsIURI *aDocumentURI, 1.101 + nsIDOMDocument *aDocument, 1.102 + nsIFile *aCustomProfileDir, 1.103 + uint32_t aAppID, 1.104 + bool aInBrowser) 1.105 +{ 1.106 + if (!EnsureUpdate()) 1.107 + return NS_ERROR_NULL_POINTER; 1.108 + 1.109 + mDocumentURI = aDocumentURI; 1.110 + 1.111 + if (aDocument) 1.112 + SetDocument(aDocument); 1.113 + 1.114 + return mUpdate->Init(aManifestURI, aDocumentURI, nullptr, aCustomProfileDir, aAppID, aInBrowser); 1.115 +} 1.116 + 1.117 +void 1.118 +OfflineCacheUpdateGlue::SetDocument(nsIDOMDocument *aDocument) 1.119 +{ 1.120 + // The design is one document for one cache update on the content process. 1.121 + NS_ASSERTION(!mDocument, 1.122 + "Setting more then a single document on an instance of OfflineCacheUpdateGlue"); 1.123 + 1.124 + LOG(("Document %p added to update glue %p", aDocument, this)); 1.125 + 1.126 + // Add document only if it was not loaded from an offline cache. 1.127 + // If it were loaded from an offline cache then it has already 1.128 + // been associated with it and must not be again cached as 1.129 + // implicit (which are the reasons we collect documents here). 1.130 + nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument); 1.131 + if (!document) 1.132 + return; 1.133 + 1.134 + nsIChannel* channel = document->GetChannel(); 1.135 + nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel = 1.136 + do_QueryInterface(channel); 1.137 + if (!appCacheChannel) 1.138 + return; 1.139 + 1.140 + bool loadedFromAppCache; 1.141 + appCacheChannel->GetLoadedFromApplicationCache(&loadedFromAppCache); 1.142 + if (loadedFromAppCache) 1.143 + return; 1.144 + 1.145 + if (EnsureUpdate()) { 1.146 + mUpdate->StickDocument(mDocumentURI); 1.147 + } 1.148 + 1.149 + mDocument = aDocument; 1.150 +} 1.151 + 1.152 +NS_IMETHODIMP 1.153 +OfflineCacheUpdateGlue::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, uint32_t state) 1.154 +{ 1.155 + if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) { 1.156 + LOG(("OfflineCacheUpdateGlue got STATE_FINISHED [%p]", this)); 1.157 + 1.158 + nsCOMPtr<nsIObserverService> observerService = 1.159 + mozilla::services::GetObserverService(); 1.160 + if (observerService) { 1.161 + LOG(("Calling offline-cache-update-completed")); 1.162 + observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this), 1.163 + "offline-cache-update-completed", 1.164 + nullptr); 1.165 + LOG(("Done offline-cache-update-completed")); 1.166 + } 1.167 + 1.168 + aUpdate->RemoveObserver(this); 1.169 + } 1.170 + 1.171 + return NS_OK; 1.172 +} 1.173 + 1.174 +NS_IMETHODIMP 1.175 +OfflineCacheUpdateGlue::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache) 1.176 +{ 1.177 + NS_ENSURE_ARG(aApplicationCache); 1.178 + 1.179 + // Check that the document that requested this update was 1.180 + // previously associated with an application cache. If not, it 1.181 + // should be associated with the new one. 1.182 + nsCOMPtr<nsIApplicationCacheContainer> container = 1.183 + do_QueryInterface(mDocument); 1.184 + if (!container) 1.185 + return NS_OK; 1.186 + 1.187 + nsCOMPtr<nsIApplicationCache> existingCache; 1.188 + nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache)); 1.189 + NS_ENSURE_SUCCESS(rv, rv); 1.190 + 1.191 + if (!existingCache) { 1.192 +#if defined(PR_LOGGING) 1.193 + if (LOG_ENABLED()) { 1.194 + nsAutoCString clientID; 1.195 + if (aApplicationCache) { 1.196 + aApplicationCache->GetClientID(clientID); 1.197 + } 1.198 + LOG(("Update %p: associating app cache %s to document %p", 1.199 + this, clientID.get(), mDocument.get())); 1.200 + } 1.201 +#endif 1.202 + 1.203 + rv = container->SetApplicationCache(aApplicationCache); 1.204 + NS_ENSURE_SUCCESS(rv, rv); 1.205 + } 1.206 + 1.207 + return NS_OK; 1.208 +} 1.209 + 1.210 +} 1.211 +}