michael@0: /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "OfflineCacheUpdateParent.h" michael@0: michael@0: #include "mozilla/dom/TabParent.h" michael@0: #include "mozilla/ipc/URIUtils.h" michael@0: #include "mozilla/unused.h" michael@0: #include "nsOfflineCacheUpdate.h" michael@0: #include "nsIApplicationCache.h" michael@0: #include "nsIScriptSecurityManager.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsContentUtils.h" michael@0: michael@0: using namespace mozilla::ipc; michael@0: using mozilla::dom::TabParent; michael@0: michael@0: #if defined(PR_LOGGING) michael@0: // michael@0: // To enable logging (see prlog.h for full details): michael@0: // michael@0: // set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5 michael@0: // set NSPR_LOG_FILE=offlineupdate.log michael@0: // michael@0: // this enables PR_LOG_ALWAYS level information and places all output in michael@0: // the file offlineupdate.log michael@0: // michael@0: extern PRLogModuleInfo *gOfflineCacheUpdateLog; michael@0: #endif michael@0: michael@0: #undef LOG michael@0: #define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args) michael@0: michael@0: #undef LOG_ENABLED michael@0: #define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4) michael@0: michael@0: namespace mozilla { michael@0: namespace docshell { michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // OfflineCacheUpdateParent::nsISupports michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: NS_IMPL_ISUPPORTS(OfflineCacheUpdateParent, michael@0: nsIOfflineCacheUpdateObserver, michael@0: nsILoadContext) michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // OfflineCacheUpdateParent michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: OfflineCacheUpdateParent::OfflineCacheUpdateParent(uint32_t aAppId, michael@0: bool aIsInBrowser) michael@0: : mIPCClosed(false) michael@0: , mIsInBrowserElement(aIsInBrowser) michael@0: , mAppId(aAppId) michael@0: { michael@0: // Make sure the service has been initialized michael@0: nsOfflineCacheUpdateService::EnsureService(); michael@0: michael@0: LOG(("OfflineCacheUpdateParent::OfflineCacheUpdateParent [%p]", this)); michael@0: } michael@0: michael@0: OfflineCacheUpdateParent::~OfflineCacheUpdateParent() michael@0: { michael@0: LOG(("OfflineCacheUpdateParent::~OfflineCacheUpdateParent [%p]", this)); michael@0: } michael@0: michael@0: void michael@0: OfflineCacheUpdateParent::ActorDestroy(ActorDestroyReason why) michael@0: { michael@0: mIPCClosed = true; michael@0: } michael@0: michael@0: nsresult michael@0: OfflineCacheUpdateParent::Schedule(const URIParams& aManifestURI, michael@0: const URIParams& aDocumentURI, michael@0: const bool& stickDocument) michael@0: { michael@0: LOG(("OfflineCacheUpdateParent::RecvSchedule [%p]", this)); michael@0: michael@0: nsRefPtr update; michael@0: nsCOMPtr manifestURI = DeserializeURI(aManifestURI); michael@0: if (!manifestURI) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsOfflineCacheUpdateService* service = michael@0: nsOfflineCacheUpdateService::EnsureService(); michael@0: if (!service) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: bool offlinePermissionAllowed = false; michael@0: michael@0: nsCOMPtr principal; michael@0: nsContentUtils::GetSecurityManager()-> michael@0: GetAppCodebasePrincipal(manifestURI, mAppId, mIsInBrowserElement, michael@0: getter_AddRefs(principal)); michael@0: michael@0: nsresult rv = service->OfflineAppAllowed( michael@0: principal, nullptr, &offlinePermissionAllowed); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (!offlinePermissionAllowed) michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: michael@0: nsCOMPtr documentURI = DeserializeURI(aDocumentURI); michael@0: if (!documentURI) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: if (!NS_SecurityCompareURIs(manifestURI, documentURI, false)) michael@0: return NS_ERROR_DOM_SECURITY_ERR; michael@0: michael@0: service->FindUpdate(manifestURI, mAppId, mIsInBrowserElement, michael@0: getter_AddRefs(update)); michael@0: if (!update) { michael@0: update = new nsOfflineCacheUpdate(); michael@0: michael@0: // Leave aDocument argument null. Only glues and children keep michael@0: // document instances. michael@0: rv = update->Init(manifestURI, documentURI, nullptr, nullptr, michael@0: mAppId, mIsInBrowserElement); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = update->Schedule(); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: update->AddObserver(this, false); michael@0: michael@0: if (stickDocument) { michael@0: nsCOMPtr stickURI; michael@0: documentURI->Clone(getter_AddRefs(stickURI)); michael@0: update->StickDocument(stickURI); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, uint32_t state) michael@0: { michael@0: if (mIPCClosed) michael@0: return NS_ERROR_UNEXPECTED; michael@0: michael@0: LOG(("OfflineCacheUpdateParent::StateEvent [%p]", this)); michael@0: michael@0: uint64_t byteProgress; michael@0: aUpdate->GetByteProgress(&byteProgress); michael@0: unused << SendNotifyStateEvent(state, byteProgress); michael@0: michael@0: if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) { michael@0: // Tell the child the particulars after the update has finished. michael@0: // Sending the Finish event will release the child side of the protocol michael@0: // and notify "offline-cache-update-completed" on the child process. michael@0: bool isUpgrade; michael@0: aUpdate->GetIsUpgrade(&isUpgrade); michael@0: bool succeeded; michael@0: aUpdate->GetSucceeded(&succeeded); michael@0: michael@0: unused << SendFinish(succeeded, isUpgrade); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache) michael@0: { michael@0: if (mIPCClosed) michael@0: return NS_ERROR_UNEXPECTED; michael@0: michael@0: NS_ENSURE_ARG(aApplicationCache); michael@0: michael@0: nsCString cacheClientId; michael@0: aApplicationCache->GetClientID(cacheClientId); michael@0: nsCString cacheGroupId; michael@0: aApplicationCache->GetGroupID(cacheGroupId); michael@0: michael@0: unused << SendAssociateDocuments(cacheGroupId, cacheClientId); michael@0: return NS_OK; michael@0: } michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // OfflineCacheUpdateParent::nsILoadContext michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetAssociatedWindow(nsIDOMWindow * *aAssociatedWindow) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetTopWindow(nsIDOMWindow * *aTopWindow) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetTopFrameElement(nsIDOMElement** aElement) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::IsAppOfType(uint32_t appType, bool *_retval) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetIsContent(bool *aIsContent) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetUsePrivateBrowsing(bool *aUsePrivateBrowsing) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::SetPrivateBrowsing(bool aUsePrivateBrowsing) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetUseRemoteTabs(bool *aUseRemoteTabs) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::SetRemoteTabs(bool aUseRemoteTabs) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetIsInBrowserElement(bool *aIsInBrowserElement) michael@0: { michael@0: *aIsInBrowserElement = mIsInBrowserElement; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: OfflineCacheUpdateParent::GetAppId(uint32_t *aAppId) michael@0: { michael@0: *aAppId = mAppId; michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // docshell michael@0: } // mozilla