зеркало из https://github.com/mozilla/pjs.git
Bug 536295 - e10s HTTP: offline application cache, r=dwitte, sr=cbiesinger, a=fennec-2.0b2+
--HG-- rename : uriloader/prefetch/nsOfflineCacheUpdate.cpp => uriloader/prefetch/OfflineCacheUpdateChild.cpp rename : uriloader/prefetch/nsOfflineCacheUpdate.cpp => uriloader/prefetch/nsOfflineCacheUpdateService.cpp
This commit is contained in:
Родитель
7b00a05d5e
Коммит
e3cf711385
|
@ -5735,7 +5735,7 @@ var OfflineApps = {
|
|||
|
||||
var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
|
||||
getService(Ci.nsIOfflineCacheUpdateService);
|
||||
updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject);
|
||||
updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject, window);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
#include "nsIApplicationCache.h"
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
#include "nsIApplicationCacheChannel.h"
|
||||
#include "nsIApplicationCacheService.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIDOMLoadStatus.h"
|
||||
#include "nsICookieService.h"
|
||||
|
@ -942,29 +941,6 @@ nsContentSink::PrefetchDNS(const nsAString &aHref)
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey)
|
||||
{
|
||||
aCacheKey.Truncate();
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(aChannel, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> cacheKey;
|
||||
rv = cachingChannel->GetCacheKey(getter_AddRefs(cacheKey));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupportsCString> cacheKeyString =
|
||||
do_QueryInterface(cacheKey, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = cacheKeyString->GetData(aCacheKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
|
||||
nsIURI *aManifestURI,
|
||||
|
@ -994,17 +970,8 @@ nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!equal) {
|
||||
// This is a foreign entry, mark it as such and force a reload to avoid
|
||||
// loading the foreign entry. The next attempt will not choose this
|
||||
// cache entry (because it has been marked foreign).
|
||||
|
||||
nsCAutoString cachekey;
|
||||
rv = GetChannelCacheKey(mDocument->GetChannel(), cachekey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aLoadApplicationCache->MarkEntry(cachekey,
|
||||
nsIApplicationCache::ITEM_FOREIGN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// This is a foreign entry, force a reload to avoid loading the foreign
|
||||
// entry. The entry will be marked as foreign to avoid loading it again.
|
||||
|
||||
*aAction = CACHE_SELECTION_RELOAD;
|
||||
}
|
||||
|
@ -1219,6 +1186,13 @@ nsContentSink::ProcessOfflineManifest(const nsAString& aManifestSpec)
|
|||
case CACHE_SELECTION_RELOAD: {
|
||||
// This situation occurs only for toplevel documents, see bottom
|
||||
// of SelectDocAppCache method.
|
||||
// The document has been loaded from a different offline cache group than
|
||||
// the manifest it refers to, i.e. this is a foreign entry, mark it as such
|
||||
// and force a reload to avoid loading it. The next attempt will not
|
||||
// choose it.
|
||||
|
||||
applicationCacheChannel->MarkOfflineCacheEntryAsForeign();
|
||||
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(mDocShell);
|
||||
|
||||
webNav->Stop(nsIWebNavigation::STOP_ALL);
|
||||
|
|
|
@ -230,6 +230,10 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
|||
#include "nsIChannelPolicy.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
#include "nsXULAppAPI.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// Number of documents currently loading
|
||||
|
@ -5928,7 +5932,13 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
|
|||
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
|
||||
do_QueryInterface(aNewChannel);
|
||||
if (appCacheChannel) {
|
||||
appCacheChannel->SetChooseApplicationCache(ShouldCheckAppCache(newURI));
|
||||
#ifdef MOZ_IPC
|
||||
// Permission will be checked in the parent process.
|
||||
if (GeckoProcessType_Default != XRE_GetProcessType())
|
||||
appCacheChannel->SetChooseApplicationCache(PR_TRUE);
|
||||
else
|
||||
#endif
|
||||
appCacheChannel->SetChooseApplicationCache(ShouldCheckAppCache(newURI));
|
||||
}
|
||||
|
||||
if (!(aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) &&
|
||||
|
@ -8581,7 +8591,14 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
|||
|
||||
// Loads with the correct permissions should check for a matching
|
||||
// application cache.
|
||||
appCacheChannel->SetChooseApplicationCache(ShouldCheckAppCache(aURI));
|
||||
#ifdef MOZ_IPC
|
||||
// Permission will be checked in the parent process
|
||||
if (GeckoProcessType_Default != XRE_GetProcessType())
|
||||
appCacheChannel->SetChooseApplicationCache(PR_TRUE);
|
||||
else
|
||||
#endif
|
||||
appCacheChannel->SetChooseApplicationCache(
|
||||
ShouldCheckAppCache(aURI));
|
||||
}
|
||||
|
||||
// Make sure to give the caller a channel if we managed to create one
|
||||
|
|
|
@ -8164,6 +8164,22 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!nsCRT::strcmp(aTopic, "offline-cache-update-added")) {
|
||||
if (mApplicationCache)
|
||||
return NS_OK;
|
||||
|
||||
// Instantiate the application object now. It observes update belonging to
|
||||
// this window's document and correctly updates the applicationCache object
|
||||
// state.
|
||||
nsCOMPtr<nsIDOMOfflineResourceList> applicationCache;
|
||||
GetApplicationCache(getter_AddRefs(applicationCache));
|
||||
nsCOMPtr<nsIObserver> observer = do_QueryInterface(applicationCache);
|
||||
if (observer)
|
||||
observer->Observe(aSubject, aTopic, aData);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_WARNING("unrecognized topic in nsGlobalWindow::Observe");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::net;
|
||||
using namespace mozilla::places;
|
||||
using namespace mozilla::docshell;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
|
@ -44,6 +44,7 @@ include protocol PDocumentRendererShmem;
|
|||
include protocol PDocumentRendererNativeID;
|
||||
include protocol PContentPermissionRequest;
|
||||
include protocol PRenderFrame;
|
||||
include protocol POfflineCacheUpdate;
|
||||
|
||||
include "TabMessageUtils.h";
|
||||
include "gfxMatrix.h";
|
||||
|
@ -73,6 +74,7 @@ rpc protocol PBrowser
|
|||
manages PDocumentRendererNativeID;
|
||||
manages PContentPermissionRequest;
|
||||
manages PRenderFrame;
|
||||
manages POfflineCacheUpdate;
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, nsString aJSON);
|
||||
|
@ -187,6 +189,33 @@ parent:
|
|||
*/
|
||||
async PRenderFrame();
|
||||
|
||||
/**
|
||||
* Starts an offline application cache update.
|
||||
* @param manifestURI
|
||||
* URI of the manifest to fetch, the application cache group ID
|
||||
* @param documentURI
|
||||
* URI of the document that referred the manifest
|
||||
* @param clientID
|
||||
* The group cache version identifier to use
|
||||
* @param stickDocument
|
||||
* True if the update was initiated by a document load that referred
|
||||
* a manifest.
|
||||
* False if the update was initiated by applicationCache.update() call.
|
||||
*
|
||||
* Tells the update to carry the documentURI to a potential separate
|
||||
* update of implicit (master) items.
|
||||
*
|
||||
* Why this argument? If the document was not found in an offline cache
|
||||
* before load and refers a manifest and this manifest itself has not
|
||||
* been changed since the last fetch, we will not do the application
|
||||
* cache group update. But we must cache the document (identified by the
|
||||
* documentURI). This argument will ensure that a previously uncached
|
||||
* document will get cached and that we don't re-cache a document that
|
||||
* has already been cached (stickDocument=false).
|
||||
*/
|
||||
POfflineCacheUpdate(URI manifestURI, URI documentURI, nsCString clientID,
|
||||
bool stickDocument);
|
||||
|
||||
__delete__();
|
||||
|
||||
child:
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "mozilla/dom/PContentDialogChild.h"
|
||||
#include "mozilla/layers/PLayersChild.h"
|
||||
#include "mozilla/layout/RenderFrameChild.h"
|
||||
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
|
||||
|
||||
#include "BasicLayers.h"
|
||||
#include "nsIWebBrowser.h"
|
||||
|
@ -94,6 +95,7 @@
|
|||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::layout;
|
||||
using namespace mozilla::docshell;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
|
||||
|
||||
|
@ -809,6 +811,24 @@ TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture)
|
|||
return true;
|
||||
}
|
||||
|
||||
POfflineCacheUpdateChild*
|
||||
TabChild::AllocPOfflineCacheUpdate(const URI& manifestURI,
|
||||
const URI& documentURI,
|
||||
const nsCString& clientID,
|
||||
const bool& stickDocument)
|
||||
{
|
||||
NS_RUNTIMEABORT("unused");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* actor)
|
||||
{
|
||||
OfflineCacheUpdateChild* offlineCacheUpdate = static_cast<OfflineCacheUpdateChild*>(actor);
|
||||
delete offlineCacheUpdate;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvLoadRemoteScript(const nsString& aURL)
|
||||
{
|
||||
|
|
|
@ -277,6 +277,12 @@ public:
|
|||
virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
|
||||
virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor);
|
||||
|
||||
virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URI& manifestURI,
|
||||
const URI& documentURI,
|
||||
const nsCString& clientID,
|
||||
const bool& stickDocument);
|
||||
virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* offlineCacheUpdate);
|
||||
|
||||
nsIWebNavigation* WebNavigation() { return mWebNav; }
|
||||
|
||||
JSContext* GetJSContext() { return mCx; }
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "mozilla/ipc/DocumentRendererShmemParent.h"
|
||||
#include "mozilla/ipc/DocumentRendererNativeIDParent.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
@ -703,6 +704,35 @@ TabParent::DeallocPRenderFrame(PRenderFrameParent* aFrame)
|
|||
return true;
|
||||
}
|
||||
|
||||
mozilla::docshell::POfflineCacheUpdateParent*
|
||||
TabParent::AllocPOfflineCacheUpdate(const URI& aManifestURI,
|
||||
const URI& aDocumentURI,
|
||||
const nsCString& aClientID,
|
||||
const bool& stickDocument)
|
||||
{
|
||||
nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
|
||||
new mozilla::docshell::OfflineCacheUpdateParent();
|
||||
|
||||
nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aClientID,
|
||||
stickDocument);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
POfflineCacheUpdateParent* result = update.get();
|
||||
update.forget();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::DeallocPOfflineCacheUpdate(mozilla::docshell::POfflineCacheUpdateParent* actor)
|
||||
{
|
||||
mozilla::docshell::OfflineCacheUpdateParent* update =
|
||||
static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(actor);
|
||||
|
||||
update->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
PRBool
|
||||
TabParent::ShouldDelayDialogs()
|
||||
{
|
||||
|
|
|
@ -170,6 +170,13 @@ public:
|
|||
virtual PContentPermissionRequestParent* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
|
||||
virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor);
|
||||
|
||||
virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdate(
|
||||
const URI& aManifestURI,
|
||||
const URI& aDocumentURI,
|
||||
const nsCString& aClientID,
|
||||
const bool& stickDocument);
|
||||
virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateParent* actor);
|
||||
|
||||
JSBool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
|
|
@ -57,6 +57,15 @@
|
|||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
#include "nsXULAppAPI.h"
|
||||
#define IS_CHILD_PROCESS() \
|
||||
(GeckoProcessType_Default != XRE_GetProcessType())
|
||||
#else
|
||||
#define IS_CHILD_PROCESS() \
|
||||
(false)
|
||||
#endif
|
||||
|
||||
// Event names
|
||||
|
||||
#define CHECKING_STR "checking"
|
||||
|
@ -137,6 +146,8 @@ nsDOMOfflineResourceList::nsDOMOfflineResourceList(nsIURI *aManifestURI,
|
|||
, mDocumentURI(aDocumentURI)
|
||||
, mCachedKeys(nsnull)
|
||||
, mCachedKeysCount(0)
|
||||
, mExposeCacheUpdateStatus(true)
|
||||
, mStatus(nsIDOMOfflineResourceList::IDLE)
|
||||
{
|
||||
mOwner = aWindow;
|
||||
mScriptContext = aScriptContext;
|
||||
|
@ -170,26 +181,29 @@ nsDOMOfflineResourceList::Init()
|
|||
if (!innerURI)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mApplicationCacheService =
|
||||
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Check for in-progress cache updates
|
||||
nsCOMPtr<nsIOfflineCacheUpdateService> cacheUpdateService =
|
||||
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 numUpdates;
|
||||
rv = cacheUpdateService->GetNumUpdates(&numUpdates);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRUint32 i = 0; i < numUpdates; i++) {
|
||||
nsCOMPtr<nsIOfflineCacheUpdate> cacheUpdate;
|
||||
rv = cacheUpdateService->GetUpdate(i, getter_AddRefs(cacheUpdate));
|
||||
if (!IS_CHILD_PROCESS())
|
||||
{
|
||||
mApplicationCacheService =
|
||||
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateAdded(cacheUpdate);
|
||||
// Check for in-progress cache updates
|
||||
nsCOMPtr<nsIOfflineCacheUpdateService> cacheUpdateService =
|
||||
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 numUpdates;
|
||||
rv = cacheUpdateService->GetNumUpdates(&numUpdates);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRUint32 i = 0; i < numUpdates; i++) {
|
||||
nsCOMPtr<nsIOfflineCacheUpdate> cacheUpdate;
|
||||
rv = cacheUpdateService->GetUpdate(i, getter_AddRefs(cacheUpdate));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateAdded(cacheUpdate);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
// watch for new offline cache updates
|
||||
|
@ -235,6 +249,9 @@ nsDOMOfflineResourceList::Disconnect()
|
|||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::GetMozItems(nsIDOMDOMStringList **aItems)
|
||||
{
|
||||
if (IS_CHILD_PROCESS())
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
*aItems = nsnull;
|
||||
|
||||
nsRefPtr<nsDOMStringList> items = new nsDOMStringList();
|
||||
|
@ -270,6 +287,9 @@ nsDOMOfflineResourceList::GetMozItems(nsIDOMDOMStringList **aItems)
|
|||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::MozHasItem(const nsAString& aURI, PRBool* aExists)
|
||||
{
|
||||
if (IS_CHILD_PROCESS())
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
nsresult rv = Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -297,6 +317,9 @@ nsDOMOfflineResourceList::MozHasItem(const nsAString& aURI, PRBool* aExists)
|
|||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::GetMozLength(PRUint32 *aLength)
|
||||
{
|
||||
if (IS_CHILD_PROCESS())
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (!mManifestURI) {
|
||||
*aLength = 0;
|
||||
return NS_OK;
|
||||
|
@ -315,6 +338,9 @@ nsDOMOfflineResourceList::GetMozLength(PRUint32 *aLength)
|
|||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::MozItem(PRUint32 aIndex, nsAString& aURI)
|
||||
{
|
||||
if (IS_CHILD_PROCESS())
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
nsresult rv = Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -334,6 +360,9 @@ nsDOMOfflineResourceList::MozItem(PRUint32 aIndex, nsAString& aURI)
|
|||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::MozAdd(const nsAString& aURI)
|
||||
{
|
||||
if (IS_CHILD_PROCESS())
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
nsresult rv = Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -398,6 +427,9 @@ nsDOMOfflineResourceList::MozAdd(const nsAString& aURI)
|
|||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::MozRemove(const nsAString& aURI)
|
||||
{
|
||||
if (IS_CHILD_PROCESS())
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
nsresult rv = Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -453,26 +485,14 @@ nsDOMOfflineResourceList::GetStatus(PRUint16 *aStatus)
|
|||
|
||||
|
||||
// If there is an update in process, use its status.
|
||||
if (mCacheUpdate) {
|
||||
if (mCacheUpdate && mExposeCacheUpdateStatus) {
|
||||
rv = mCacheUpdate->GetStatus(aStatus);
|
||||
if (NS_SUCCEEDED(rv) && *aStatus != nsIDOMOfflineResourceList::IDLE) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIApplicationCache> activeCache;
|
||||
rv = mApplicationCacheService->GetActiveCache(mManifestSpec,
|
||||
getter_AddRefs(activeCache));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (activeCache == nsnull) {
|
||||
*aStatus = nsIDOMOfflineResourceList::OBSOLETE;
|
||||
} else if (appCache == activeCache) {
|
||||
*aStatus = nsIDOMOfflineResourceList::IDLE;
|
||||
} else {
|
||||
*aStatus = nsIDOMOfflineResourceList::UPDATEREADY;
|
||||
}
|
||||
|
||||
*aStatus = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -490,9 +510,12 @@ nsDOMOfflineResourceList::Update()
|
|||
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window =
|
||||
do_QueryInterface(mOwner);
|
||||
|
||||
nsCOMPtr<nsIOfflineCacheUpdate> update;
|
||||
rv = updateService->ScheduleUpdate(mManifestURI, mDocumentURI,
|
||||
getter_AddRefs(update));
|
||||
window, getter_AddRefs(update));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -508,33 +531,39 @@ nsDOMOfflineResourceList::SwapCache()
|
|||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheService> serv =
|
||||
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIApplicationCache> currentAppCache = GetDocumentAppCache();
|
||||
|
||||
nsCOMPtr<nsIApplicationCache> newAppCache;
|
||||
rv = serv->GetActiveCache(mManifestSpec, getter_AddRefs(newAppCache));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// In the case of an obsolete cache group, newAppCache might be null.
|
||||
// We will disassociate from the cache in that case.
|
||||
|
||||
if (newAppCache == currentAppCache) {
|
||||
if (!currentAppCache) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
// Check the current and potentially newly available cache are not identical.
|
||||
if (mAvailableApplicationCache == currentAppCache) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
if (mAvailableApplicationCache) {
|
||||
nsCString currClientId, availClientId;
|
||||
currentAppCache->GetClientID(currClientId);
|
||||
mAvailableApplicationCache->GetClientID(availClientId);
|
||||
if (availClientId == currClientId)
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
ClearCachedKeys();
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer =
|
||||
GetDocumentAppCacheContainer();
|
||||
|
||||
// In the case of an obsolete cache group, newAppCache might be null.
|
||||
// We will disassociate from the cache in that case.
|
||||
if (appCacheContainer) {
|
||||
rv = appCacheContainer->SetApplicationCache(newAppCache);
|
||||
rv = appCacheContainer->SetApplicationCache(mAvailableApplicationCache);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mAvailableApplicationCache = nsnull;
|
||||
mStatus = nsIDOMOfflineResourceList::IDLE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -727,53 +756,50 @@ nsDOMOfflineResourceList::Observe(nsISupports *aSubject,
|
|||
// nsDOMOfflineResourceList::nsIOfflineCacheUpdateObserver
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::Error(nsIOfflineCacheUpdate *aUpdate)
|
||||
nsDOMOfflineResourceList::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate,
|
||||
PRUint32 event)
|
||||
{
|
||||
SendEvent(NS_LITERAL_STRING(ERROR_STR));
|
||||
mExposeCacheUpdateStatus =
|
||||
(event == STATE_CHECKING) ||
|
||||
(event == STATE_DOWNLOADING) ||
|
||||
(event == STATE_ITEMSTARTED) ||
|
||||
(event == STATE_ITEMCOMPLETED) ||
|
||||
// During notification of "obsolete" we must expose state of the update
|
||||
(event == STATE_OBSOLETE);
|
||||
|
||||
switch (event) {
|
||||
case STATE_ERROR:
|
||||
SendEvent(NS_LITERAL_STRING(ERROR_STR));
|
||||
break;
|
||||
case STATE_CHECKING:
|
||||
SendEvent(NS_LITERAL_STRING(CHECKING_STR));
|
||||
break;
|
||||
case STATE_NOUPDATE:
|
||||
SendEvent(NS_LITERAL_STRING(NOUPDATE_STR));
|
||||
break;
|
||||
case STATE_OBSOLETE:
|
||||
mStatus = nsIDOMOfflineResourceList::OBSOLETE;
|
||||
mAvailableApplicationCache = nsnull;
|
||||
SendEvent(NS_LITERAL_STRING(OBSOLETE_STR));
|
||||
break;
|
||||
case STATE_DOWNLOADING:
|
||||
SendEvent(NS_LITERAL_STRING(DOWNLOADING_STR));
|
||||
break;
|
||||
case STATE_ITEMSTARTED:
|
||||
SendEvent(NS_LITERAL_STRING(PROGRESS_STR));
|
||||
break;
|
||||
case STATE_ITEMCOMPLETED:
|
||||
// Nothing to do here...
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::Checking(nsIOfflineCacheUpdate *aUpdate)
|
||||
nsDOMOfflineResourceList::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache)
|
||||
{
|
||||
SendEvent(NS_LITERAL_STRING(CHECKING_STR));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::NoUpdate(nsIOfflineCacheUpdate *aUpdate)
|
||||
{
|
||||
SendEvent(NS_LITERAL_STRING(NOUPDATE_STR));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::Downloading(nsIOfflineCacheUpdate *aUpdate)
|
||||
{
|
||||
SendEvent(NS_LITERAL_STRING(DOWNLOADING_STR));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::ItemStarted(nsIOfflineCacheUpdate *aUpdate,
|
||||
nsIDOMLoadStatus *aItem)
|
||||
{
|
||||
SendEvent(NS_LITERAL_STRING(PROGRESS_STR));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::ItemCompleted(nsIOfflineCacheUpdate *aUpdate,
|
||||
nsIDOMLoadStatus *aItem)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMOfflineResourceList::Obsolete(nsIOfflineCacheUpdate *aUpdate)
|
||||
{
|
||||
SendEvent(NS_LITERAL_STRING(OBSOLETE_STR));
|
||||
mAvailableApplicationCache = aApplicationCache;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -875,8 +901,10 @@ nsDOMOfflineResourceList::UpdateCompleted(nsIOfflineCacheUpdate *aUpdate)
|
|||
|
||||
if (NS_SUCCEEDED(rv) && succeeded && !partial) {
|
||||
if (isUpgrade) {
|
||||
mStatus = nsIDOMOfflineResourceList::UPDATEREADY;
|
||||
SendEvent(NS_LITERAL_STRING(UPDATEREADY_STR));
|
||||
} else {
|
||||
mStatus = nsIDOMOfflineResourceList::IDLE;
|
||||
SendEvent(NS_LITERAL_STRING(CACHED_STR));
|
||||
}
|
||||
}
|
||||
|
@ -905,6 +933,9 @@ nsDOMOfflineResourceList::GetCacheKey(nsIURI *aURI, nsCString &aKey)
|
|||
nsresult
|
||||
nsDOMOfflineResourceList::CacheKeys()
|
||||
{
|
||||
if (IS_CHILD_PROCESS())
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (mCachedKeys)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -929,6 +960,3 @@ nsDOMOfflineResourceList::ClearCachedKeys()
|
|||
mCachedKeysCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -110,7 +110,10 @@ private:
|
|||
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIApplicationCacheService> mApplicationCacheService;
|
||||
nsCOMPtr<nsIApplicationCache> mAvailableApplicationCache;
|
||||
nsCOMPtr<nsIOfflineCacheUpdate> mCacheUpdate;
|
||||
bool mExposeCacheUpdateStatus;
|
||||
PRUint16 mStatus;
|
||||
|
||||
// The set of dynamic keys for this application cache object.
|
||||
char **mCachedKeys;
|
||||
|
|
|
@ -67,6 +67,7 @@ IPDLDIRS = \
|
|||
netwerk/protocol/http \
|
||||
netwerk/protocol/wyciwyg \
|
||||
netwerk/cookie \
|
||||
uriloader/prefetch \
|
||||
$(NULL)
|
||||
##-----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -111,9 +111,16 @@ interface nsIApplicationCacheNamespace : nsISupports
|
|||
* loads. Inactive caches will be removed from the cache when they are
|
||||
* no longer referenced.
|
||||
*/
|
||||
[scriptable, uuid(663e2e2e-04a0-47b6-87b3-a122be46cb53)]
|
||||
[scriptable, uuid(32f83e3f-470c-4423-a86a-d35d1c215ccb)]
|
||||
interface nsIApplicationCache : nsISupports
|
||||
{
|
||||
/**
|
||||
* Init this application cache instance to just hold the group ID and
|
||||
* the client ID to work just as a handle to the real cache. Used on
|
||||
* content process to simplify the application cache code.
|
||||
*/
|
||||
void initAsHandle(in ACString groupId, in ACString clientId);
|
||||
|
||||
/**
|
||||
* Entries in an application cache can be marked as one or more of
|
||||
* the following types.
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
/**
|
||||
* Interface implemented by channels that support application caches.
|
||||
*/
|
||||
[scriptable, uuid(9acfd21c-9c07-459f-8dae-ed2ffba23ddc)]
|
||||
[scriptable, uuid(8d9024e6-ab01-442d-8119-2f55d55d91b0)]
|
||||
interface nsIApplicationCacheChannel : nsIApplicationCacheContainer
|
||||
{
|
||||
/**
|
||||
|
@ -75,4 +75,11 @@ interface nsIApplicationCacheChannel : nsIApplicationCacheContainer
|
|||
* is called.
|
||||
*/
|
||||
attribute boolean chooseApplicationCache;
|
||||
|
||||
/**
|
||||
* A shortcut method to mark the cache item of this channel as 'foreign'.
|
||||
* See the 'cache selection algorithm' and CACHE_SELECTION_RELOAD
|
||||
* action handling in nsContentSink.
|
||||
*/
|
||||
void markOfflineCacheEntryAsForeign();
|
||||
};
|
||||
|
|
|
@ -512,6 +512,19 @@
|
|||
{0x8e, 0x1c, 0xd1, 0xaf, 0x79, 0xdf, 0xd1, 0x2f} \
|
||||
}
|
||||
|
||||
#define NS_APPLICATIONCACHE_CLASSNAME \
|
||||
"nsApplicationCache"
|
||||
#define NS_APPLICATIONCACHE_CONTRACTID \
|
||||
"@mozilla.org/network/application-cache;1"
|
||||
|
||||
#define NS_APPLICATIONCACHE_CID \
|
||||
{ /* 463440c5-baad-4f3c-9e50-0b107abe7183 */ \
|
||||
0x463440c5, \
|
||||
0xbaad, \
|
||||
0x4f3c, \
|
||||
{0x9e, 0x50, 0xb, 0x10, 0x7a, 0xbe, 0x71, 0x83 } \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* netwerk/protocol/http/ classes
|
||||
*/
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "nsSOCKSSocketProvider.h"
|
||||
#include "nsCacheService.h"
|
||||
#include "nsDiskCacheDeviceSQL.h"
|
||||
#include "nsApplicationCache.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsNetStrings.h"
|
||||
#include "nsDNSPrefetch.h"
|
||||
|
@ -211,6 +212,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutCacheEntry)
|
|||
#ifdef NECKO_OFFLINE_CACHE
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheDevice, nsOfflineCacheDevice::GetInstance)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsApplicationCacheNamespace)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsApplicationCache)
|
||||
#endif
|
||||
|
||||
#ifdef NECKO_PROTOCOL_file
|
||||
|
@ -709,6 +711,7 @@ NS_DEFINE_NAMED_CID(NS_CACHESERVICE_CID);
|
|||
#ifdef NECKO_OFFLINE_CACHE
|
||||
NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHESERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHENAMESPACE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHE_CID);
|
||||
#endif
|
||||
#ifdef NECKO_COOKIES
|
||||
NS_DEFINE_NAMED_CID(NS_COOKIEMANAGER_CID);
|
||||
|
@ -833,6 +836,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
|
|||
#ifdef NECKO_OFFLINE_CACHE
|
||||
{ &kNS_APPLICATIONCACHESERVICE_CID, false, NULL, nsOfflineCacheDeviceConstructor },
|
||||
{ &kNS_APPLICATIONCACHENAMESPACE_CID, false, NULL, nsApplicationCacheNamespaceConstructor },
|
||||
{ &kNS_APPLICATIONCACHE_CID, false, NULL, nsApplicationCacheConstructor },
|
||||
#endif
|
||||
#ifdef NECKO_COOKIES
|
||||
{ &kNS_COOKIEMANAGER_CID, false, NULL, nsICookieServiceConstructor },
|
||||
|
@ -964,6 +968,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
|
|||
#ifdef NECKO_OFFLINE_CACHE
|
||||
{ NS_APPLICATIONCACHESERVICE_CONTRACTID, &kNS_APPLICATIONCACHESERVICE_CID },
|
||||
{ NS_APPLICATIONCACHENAMESPACE_CONTRACTID, &kNS_APPLICATIONCACHENAMESPACE_CID },
|
||||
{ NS_APPLICATIONCACHE_CONTRACTID, &kNS_APPLICATIONCACHE_CID },
|
||||
#endif
|
||||
#ifdef NECKO_COOKIES
|
||||
{ NS_COOKIEMANAGER_CONTRACTID, &kNS_COOKIEMANAGER_CID },
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et cin: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
* Portions created by Mozilla Corporation are Copyright (C) 2010
|
||||
* Mozilla Corporation. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
class nsApplicationCache : public nsIApplicationCache
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIAPPLICATIONCACHE
|
||||
|
||||
nsApplicationCache(nsOfflineCacheDevice *device,
|
||||
const nsACString &group,
|
||||
const nsACString &clientID);
|
||||
|
||||
nsApplicationCache();
|
||||
|
||||
virtual ~nsApplicationCache();
|
||||
|
||||
void MarkInvalid();
|
||||
|
||||
private:
|
||||
nsRefPtr<nsOfflineCacheDevice> mDevice;
|
||||
nsCString mGroup;
|
||||
nsCString mClientID;
|
||||
PRBool mValid;
|
||||
};
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsDiskCache.h"
|
||||
#include "nsDiskCacheDeviceSQL.h"
|
||||
#include "nsCacheService.h"
|
||||
#include "nsApplicationCache.h"
|
||||
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -594,32 +595,16 @@ nsApplicationCacheNamespace::GetData(nsACString &out)
|
|||
* nsApplicationCache
|
||||
*/
|
||||
|
||||
class nsApplicationCache : public nsIApplicationCache
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIAPPLICATIONCACHE
|
||||
|
||||
nsApplicationCache(nsOfflineCacheDevice *device,
|
||||
const nsACString &group,
|
||||
const nsACString &clientID);
|
||||
|
||||
virtual ~nsApplicationCache();
|
||||
|
||||
void MarkInvalid() { mValid = PR_FALSE; }
|
||||
|
||||
private:
|
||||
nsRefPtr<nsOfflineCacheDevice> mDevice;
|
||||
nsCString mGroup;
|
||||
nsCString mClientID;
|
||||
PRBool mValid;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsApplicationCache,
|
||||
nsIApplicationCache,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
nsApplicationCache::nsApplicationCache()
|
||||
: mDevice(nsnull)
|
||||
, mValid(PR_TRUE)
|
||||
{
|
||||
}
|
||||
|
||||
nsApplicationCache::nsApplicationCache(nsOfflineCacheDevice *device,
|
||||
const nsACString &group,
|
||||
const nsACString &clientID)
|
||||
|
@ -632,6 +617,9 @@ nsApplicationCache::nsApplicationCache(nsOfflineCacheDevice *device,
|
|||
|
||||
nsApplicationCache::~nsApplicationCache()
|
||||
{
|
||||
if (!mDevice)
|
||||
return;
|
||||
|
||||
mDevice->mCaches.Remove(mClientID);
|
||||
|
||||
// If this isn't an active cache anymore, it can be destroyed.
|
||||
|
@ -639,6 +627,24 @@ nsApplicationCache::~nsApplicationCache()
|
|||
Discard();
|
||||
}
|
||||
|
||||
void
|
||||
nsApplicationCache::MarkInvalid()
|
||||
{
|
||||
mValid = PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationCache::InitAsHandle(const nsACString &groupId,
|
||||
const nsACString &clientId)
|
||||
{
|
||||
NS_ENSURE_FALSE(mDevice, NS_ERROR_ALREADY_INITIALIZED);
|
||||
NS_ENSURE_TRUE(mGroup.IsEmpty(), NS_ERROR_ALREADY_INITIALIZED);
|
||||
|
||||
mGroup = groupId;
|
||||
mClientID = clientId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationCache::GetGroupID(nsACString &out)
|
||||
{
|
||||
|
@ -656,6 +662,8 @@ nsApplicationCache::GetClientID(nsACString &out)
|
|||
NS_IMETHODIMP
|
||||
nsApplicationCache::GetActive(PRBool *out)
|
||||
{
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
*out = mDevice->IsActiveCache(mGroup, mClientID);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -664,6 +672,7 @@ NS_IMETHODIMP
|
|||
nsApplicationCache::Activate()
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
mDevice->ActivateCache(mGroup, mClientID);
|
||||
return NS_OK;
|
||||
|
@ -673,6 +682,7 @@ NS_IMETHODIMP
|
|||
nsApplicationCache::Discard()
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
mValid = PR_FALSE;
|
||||
|
||||
|
@ -689,6 +699,7 @@ nsApplicationCache::MarkEntry(const nsACString &key,
|
|||
PRUint32 typeBits)
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return mDevice->MarkEntry(mClientID, key, typeBits);
|
||||
}
|
||||
|
@ -699,6 +710,7 @@ nsApplicationCache::UnmarkEntry(const nsACString &key,
|
|||
PRUint32 typeBits)
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return mDevice->UnmarkEntry(mClientID, key, typeBits);
|
||||
}
|
||||
|
@ -708,6 +720,7 @@ nsApplicationCache::GetTypes(const nsACString &key,
|
|||
PRUint32 *typeBits)
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return mDevice->GetTypes(mClientID, key, typeBits);
|
||||
}
|
||||
|
@ -718,6 +731,7 @@ nsApplicationCache::GatherEntries(PRUint32 typeBits,
|
|||
char *** keys)
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return mDevice->GatherEntries(mClientID, typeBits, count, keys);
|
||||
}
|
||||
|
@ -726,6 +740,7 @@ NS_IMETHODIMP
|
|||
nsApplicationCache::AddNamespaces(nsIArray *namespaces)
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
if (!namespaces)
|
||||
return NS_OK;
|
||||
|
@ -757,6 +772,7 @@ nsApplicationCache::GetMatchingNamespace(const nsACString &key,
|
|||
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return mDevice->GetMatchingNamespace(mClientID, key, out);
|
||||
}
|
||||
|
@ -765,6 +781,7 @@ NS_IMETHODIMP
|
|||
nsApplicationCache::GetUsage(PRUint32 *usage)
|
||||
{
|
||||
NS_ENSURE_TRUE(mValid, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mDevice, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return mDevice->GetUsage(mClientID, usage);
|
||||
}
|
||||
|
|
|
@ -184,6 +184,21 @@ class StartRequestEvent : public ChannelEvent
|
|||
nsCString mSecurityInfoSerialization;
|
||||
};
|
||||
|
||||
bool
|
||||
HttpChannelChild::RecvAssociateApplicationCache(const nsCString &groupID,
|
||||
const nsCString &clientID)
|
||||
{
|
||||
nsresult rv;
|
||||
mApplicationCache = do_CreateInstance(
|
||||
NS_APPLICATIONCACHE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return true;
|
||||
|
||||
mLoadedFromApplicationCache = PR_TRUE;
|
||||
mApplicationCache->InitAsHandle(groupID, clientID);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
|
||||
const PRBool& useResponseHead,
|
||||
|
@ -878,6 +893,22 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCString appCacheClientId;
|
||||
if (mInheritApplicationCache) {
|
||||
// Pick up an application cache from the notification
|
||||
// callbacks if available
|
||||
nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer;
|
||||
GetCallback(appCacheContainer);
|
||||
|
||||
if (appCacheContainer) {
|
||||
nsCOMPtr<nsIApplicationCache> appCache;
|
||||
rv = appCacheContainer->GetApplicationCache(getter_AddRefs(appCache));
|
||||
if (NS_SUCCEEDED(rv) && appCache) {
|
||||
appCache->GetClientID(appCacheClientId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Send request to the chrome process...
|
||||
//
|
||||
|
@ -902,7 +933,8 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
|||
mRequestHeaders, mRequestHead.Method(), uploadStreamData,
|
||||
uploadStreamInfo, mPriority, mRedirectionLimit,
|
||||
mAllowPipelining, mForceAllowThirdPartyCookie, mSendResumeAt,
|
||||
mStartPos, mEntityID);
|
||||
mStartPos, mEntityID, mChooseApplicationCache,
|
||||
appCacheClientId);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1047,13 +1079,16 @@ HttpChannelChild::SetNewListener(nsIStreamListener *listener,
|
|||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetApplicationCache(nsIApplicationCache **aApplicationCache)
|
||||
{
|
||||
DROP_DEAD();
|
||||
NS_IF_ADDREF(*aApplicationCache = mApplicationCache);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::SetApplicationCache(nsIApplicationCache *aApplicationCache)
|
||||
{
|
||||
// FIXME: redirects call. so stub OK for now. Fix in bug 536295.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
||||
|
||||
mApplicationCache = aApplicationCache;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1061,34 +1096,43 @@ HttpChannelChild::SetApplicationCache(nsIApplicationCache *aApplicationCache)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetLoadedFromApplicationCache(PRBool *retval)
|
||||
HttpChannelChild::GetLoadedFromApplicationCache(PRBool *aLoadedFromApplicationCache)
|
||||
{
|
||||
// FIXME: stub for bug 536295
|
||||
*retval = 0;
|
||||
*aLoadedFromApplicationCache = mLoadedFromApplicationCache;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetInheritApplicationCache(PRBool *aInheritApplicationCache)
|
||||
HttpChannelChild::GetInheritApplicationCache(PRBool *aInherit)
|
||||
{
|
||||
DROP_DEAD();
|
||||
*aInherit = mInheritApplicationCache;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::SetInheritApplicationCache(PRBool aInheritApplicationCache)
|
||||
HttpChannelChild::SetInheritApplicationCache(PRBool aInherit)
|
||||
{
|
||||
// FIXME: Browser calls this early, so stub OK for now. Fix in bug 536295.
|
||||
mInheritApplicationCache = aInherit;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::GetChooseApplicationCache(PRBool *aChooseApplicationCache)
|
||||
HttpChannelChild::GetChooseApplicationCache(PRBool *aChoose)
|
||||
{
|
||||
DROP_DEAD();
|
||||
*aChoose = mChooseApplicationCache;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::SetChooseApplicationCache(PRBool aChooseApplicationCache)
|
||||
HttpChannelChild::SetChooseApplicationCache(PRBool aChoose)
|
||||
{
|
||||
// FIXME: Browser calls this early, so stub OK for now. Fix in bug 536295.
|
||||
mChooseApplicationCache = aChoose;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::MarkOfflineCacheEntryAsForeign()
|
||||
{
|
||||
SendMarkOfflineCacheEntryAsForeign();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,8 @@ protected:
|
|||
const PRUint32& redirectFlags,
|
||||
const nsHttpResponseHead& responseHead);
|
||||
bool RecvRedirect3Complete();
|
||||
bool RecvAssociateApplicationCache(const nsCString& groupID,
|
||||
const nsCString& clientID);
|
||||
bool RecvDeleteSelf();
|
||||
|
||||
bool GetAssociatedContentSecurity(nsIAssociatedContentSecurity** res = nsnull);
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
#include "nsSerializationHelper.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsIAssociatedContentSecurity.h"
|
||||
#include "nsIApplicationCacheService.h"
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -110,7 +112,9 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
|
|||
const PRBool& forceAllowThirdPartyCookie,
|
||||
const bool& doResumeAt,
|
||||
const PRUint64& startPos,
|
||||
const nsCString& entityID)
|
||||
const nsCString& entityID,
|
||||
const bool& chooseApplicationCache,
|
||||
const nsCString& appCacheClientID)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri(aURI);
|
||||
nsCOMPtr<nsIURI> originalUri(aOriginalURI);
|
||||
|
@ -176,6 +180,41 @@ HttpChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
|
|||
httpChan->SetAllowPipelining(allowPipelining);
|
||||
httpChan->SetForceAllowThirdPartyCookie(forceAllowThirdPartyCookie);
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheChannel> appCacheChan =
|
||||
do_QueryInterface(mChannel);
|
||||
nsCOMPtr<nsIApplicationCacheService> appCacheService =
|
||||
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
|
||||
|
||||
PRBool setChooseApplicationCache = chooseApplicationCache;
|
||||
if (appCacheChan && appCacheService) {
|
||||
// We might potentially want to drop this flag (that is TRUE by default)
|
||||
// after we succefully associate the channel with an application cache
|
||||
// reported by the channel child. Dropping it here may be too early.
|
||||
appCacheChan->SetInheritApplicationCache(PR_FALSE);
|
||||
if (!appCacheClientID.IsEmpty()) {
|
||||
nsCOMPtr<nsIApplicationCache> appCache;
|
||||
rv = appCacheService->GetApplicationCache(appCacheClientID,
|
||||
getter_AddRefs(appCache));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
appCacheChan->SetApplicationCache(appCache);
|
||||
setChooseApplicationCache = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (setChooseApplicationCache) {
|
||||
nsCOMPtr<nsIOfflineCacheUpdateService> offlineUpdateService =
|
||||
do_GetService("@mozilla.org/offlinecacheupdate-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = offlineUpdateService->OfflineAppAllowedForURI(uri,
|
||||
nsnull,
|
||||
&setChooseApplicationCache);
|
||||
|
||||
if (setChooseApplicationCache && NS_SUCCEEDED(rv))
|
||||
appCacheChan->SetChooseApplicationCache(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = httpChan->AsyncOpen(mChannelListener, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return SendCancelEarly(rv);
|
||||
|
@ -273,6 +312,14 @@ HttpChannelParent::RecvDocumentChannelCleanup()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HttpChannelParent::RecvMarkOfflineCacheEntryAsForeign()
|
||||
{
|
||||
nsHttpChannel *httpChan = static_cast<nsHttpChannel *>(mChannel.get());
|
||||
httpChan->MarkOfflineCacheEntryAsForeign();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIRequestObserver and nsIStreamListener methods equivalents
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -296,6 +343,22 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
|||
nsCString cachedCharset;
|
||||
chan->GetCacheTokenCachedCharset(cachedCharset);
|
||||
|
||||
PRBool loadedFromApplicationCache;
|
||||
chan->GetLoadedFromApplicationCache(&loadedFromApplicationCache);
|
||||
if (loadedFromApplicationCache) {
|
||||
nsCOMPtr<nsIApplicationCache> appCache;
|
||||
chan->GetApplicationCache(getter_AddRefs(appCache));
|
||||
nsCString appCacheGroupId;
|
||||
nsCString appCacheClientId;
|
||||
appCache->GetGroupID(appCacheGroupId);
|
||||
appCache->GetClientID(appCacheClientId);
|
||||
if (mIPCClosed ||
|
||||
!SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
|
||||
{
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(aRequest);
|
||||
if (encodedChannel)
|
||||
encodedChannel->SetApplyConversion(PR_FALSE);
|
||||
|
|
|
@ -96,7 +96,9 @@ protected:
|
|||
const PRBool& forceAllowThirdPartyCookie,
|
||||
const bool& doResumeAt,
|
||||
const PRUint64& startPos,
|
||||
const nsCString& entityID);
|
||||
const nsCString& entityID,
|
||||
const bool& chooseApplicationCache,
|
||||
const nsCString& appCacheClientID);
|
||||
|
||||
virtual bool RecvSetPriority(const PRUint16& priority);
|
||||
virtual bool RecvSetCacheTokenCachedCharset(const nsCString& charset);
|
||||
|
@ -110,6 +112,7 @@ protected:
|
|||
const PRInt32& broken,
|
||||
const PRInt32& no);
|
||||
virtual bool RecvDocumentChannelCleanup();
|
||||
virtual bool RecvMarkOfflineCacheEntryAsForeign();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
|
|
|
@ -76,7 +76,9 @@ parent:
|
|||
PRBool forceAllowThirdPartyCookie,
|
||||
bool resumeAt,
|
||||
PRUint64 startPos,
|
||||
nsCString entityID);
|
||||
nsCString entityID,
|
||||
bool chooseApplicationCache,
|
||||
nsCString appCacheClientID);
|
||||
|
||||
SetPriority(PRUint16 priority);
|
||||
|
||||
|
@ -99,6 +101,21 @@ parent:
|
|||
// partial cleanup on parent.
|
||||
DocumentChannelCleanup();
|
||||
|
||||
// This might have to be sync. If this fails we must fail the document load
|
||||
// to avoid endless loop.
|
||||
//
|
||||
// Explanation: the document loaded was loaded from the offline cache. But
|
||||
// the cache group id (the manifest URL) of the cache group it was loaded
|
||||
// from is different then the manifest the document refers to in the html
|
||||
// tag. If we detect this during the cache selection algorithm, we must not
|
||||
// load this document from the offline cache group it was just loaded from.
|
||||
// Marking the cache entry as foreign in its cache group will prevent
|
||||
// the document to load from the bad offline cache group. After it is marked,
|
||||
// we reload the document to take the effect. If we fail to mark the entry
|
||||
// as foreign, we will end up in the same situation and reload again and
|
||||
// again, indefinitely.
|
||||
MarkOfflineCacheEntryAsForeign();
|
||||
|
||||
__delete__();
|
||||
|
||||
child:
|
||||
|
@ -135,6 +152,10 @@ child:
|
|||
// Called if redirect successful so that child can complete setup.
|
||||
Redirect3Complete();
|
||||
|
||||
// Associte the child with an application ids
|
||||
AssociateApplicationCache(nsCString groupID,
|
||||
nsCString clientID);
|
||||
|
||||
// Tell child to delete channel (all IPDL deletes must be done from child to
|
||||
// avoid races: see bug 591708).
|
||||
DeleteSelf();
|
||||
|
|
|
@ -4533,6 +4533,25 @@ nsHttpChannel::SetChooseApplicationCache(PRBool aChoose)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::MarkOfflineCacheEntryAsForeign()
|
||||
{
|
||||
if (!mApplicationCache)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCAutoString cacheKey;
|
||||
rv = GenerateCacheKey(mPostID, cacheKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mApplicationCache->MarkEntry(cacheKey,
|
||||
nsIApplicationCache::ITEM_FOREIGN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel::nsIAsyncVerifyRedirectCallback
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -46,22 +46,47 @@ MODULE = prefetch
|
|||
LIBRARY_NAME = prefetch_s
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
ifdef MOZ_IPC
|
||||
EXPORTS_NAMESPACES = mozilla/docshell
|
||||
|
||||
EXPORTS_mozilla/docshell += \
|
||||
OfflineCacheUpdateParent.h \
|
||||
OfflineCacheUpdateChild.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
CPPSRCS = \
|
||||
nsPrefetchService.cpp \
|
||||
nsOfflineCacheUpdate.cpp \
|
||||
nsOfflineCacheUpdateService.cpp \
|
||||
OfflineCacheUpdateGlue.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_IPC
|
||||
CPPSRCS += \
|
||||
OfflineCacheUpdateChild.cpp \
|
||||
OfflineCacheUpdateParent.cpp
|
||||
endif
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIPrefetchService.idl \
|
||||
nsIOfflineCacheUpdate.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsCPrefetchService.h \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(topsrcdir)/content/base/src \
|
||||
-I$(topsrcdir)/content/events/src \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# vim: ts=4 sw=4 noexpandtab
|
||||
|
|
|
@ -0,0 +1,533 @@
|
|||
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "OfflineCacheUpdateChild.h"
|
||||
#include "nsOfflineCacheUpdate.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
#include "nsIApplicationCacheChannel.h"
|
||||
#include "nsIApplicationCacheService.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMOfflineResourceList.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsITabChild.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nsnull;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// To enable logging (see prlog.h for full details):
|
||||
//
|
||||
// set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
|
||||
// set NSPR_LOG_FILE=offlineupdate.log
|
||||
//
|
||||
// this enables PR_LOG_ALWAYS level information and places all output in
|
||||
// the file offlineupdate.log
|
||||
//
|
||||
extern PRLogModuleInfo *gOfflineCacheUpdateLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
|
||||
#define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
|
||||
|
||||
namespace mozilla {
|
||||
namespace docshell {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OfflineCacheUpdateChild::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(OfflineCacheUpdateChild)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIOfflineCacheUpdate)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(OfflineCacheUpdateChild)
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(OfflineCacheUpdateChild, RefcountHitZero())
|
||||
|
||||
void
|
||||
OfflineCacheUpdateChild::RefcountHitZero()
|
||||
{
|
||||
if (mIPCActivated) {
|
||||
// ContentChild::DeallocPOfflineCacheUpdate will delete this
|
||||
OfflineCacheUpdateChild::Send__delete__(this);
|
||||
} else {
|
||||
delete this; // we never opened IPDL channel
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OfflineCacheUpdateChild <public>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
OfflineCacheUpdateChild::OfflineCacheUpdateChild(nsIDOMWindow* aWindow)
|
||||
: mState(STATE_UNINITIALIZED)
|
||||
, mIsUpgrade(PR_FALSE)
|
||||
, mIPCActivated(PR_FALSE)
|
||||
, mWindow(aWindow)
|
||||
{
|
||||
}
|
||||
|
||||
OfflineCacheUpdateChild::~OfflineCacheUpdateChild()
|
||||
{
|
||||
LOG(("OfflineCacheUpdateChild::~OfflineCacheUpdateChild [%p]", this));
|
||||
}
|
||||
|
||||
nsresult
|
||||
OfflineCacheUpdateChild::GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers)
|
||||
{
|
||||
for (PRInt32 i = 0; i < mWeakObservers.Count(); i++) {
|
||||
nsCOMPtr<nsIOfflineCacheUpdateObserver> observer =
|
||||
do_QueryReferent(mWeakObservers[i]);
|
||||
if (observer)
|
||||
aObservers.AppendObject(observer);
|
||||
else
|
||||
mWeakObservers.RemoveObjectAt(i--);
|
||||
}
|
||||
|
||||
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
||||
aObservers.AppendObject(mObservers[i]);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
OfflineCacheUpdateChild::SetDocument(nsIDOMDocument *aDocument)
|
||||
{
|
||||
// The design is one document for one cache update on the content process.
|
||||
NS_ASSERTION(!mDocument, "Setting more then a single document on a child offline cache update");
|
||||
|
||||
LOG(("Document %p added to update child %p", aDocument, this));
|
||||
|
||||
// Add document only if it was not loaded from an offline cache.
|
||||
// If it were loaded from an offline cache then it has already
|
||||
// been associated with it and must not be again cached as
|
||||
// implicit (which are the reasons we collect documents here).
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
|
||||
if (!document)
|
||||
return;
|
||||
|
||||
nsIChannel* channel = document->GetChannel();
|
||||
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
|
||||
do_QueryInterface(channel);
|
||||
if (!appCacheChannel)
|
||||
return;
|
||||
|
||||
PRBool loadedFromAppCache;
|
||||
appCacheChannel->GetLoadedFromApplicationCache(&loadedFromAppCache);
|
||||
if (loadedFromAppCache)
|
||||
return;
|
||||
|
||||
mDocument = aDocument;
|
||||
}
|
||||
|
||||
nsresult
|
||||
OfflineCacheUpdateChild::AssociateDocument(nsIDOMDocument *aDocument,
|
||||
nsIApplicationCache *aApplicationCache)
|
||||
{
|
||||
// Check that the document that requested this update was
|
||||
// previously associated with an application cache. If not, it
|
||||
// should be associated with the new one.
|
||||
nsCOMPtr<nsIApplicationCacheContainer> container =
|
||||
do_QueryInterface(aDocument);
|
||||
if (!container)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIApplicationCache> existingCache;
|
||||
nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!existingCache) {
|
||||
#if defined(PR_LOGGING)
|
||||
if (LOG_ENABLED()) {
|
||||
nsCAutoString clientID;
|
||||
if (aApplicationCache) {
|
||||
aApplicationCache->GetClientID(clientID);
|
||||
}
|
||||
LOG(("Update %p: associating app cache %s to document %p",
|
||||
this, clientID.get(), aDocument));
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = container->SetApplicationCache(aApplicationCache);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OfflineCacheUpdateChild::nsIOfflineCacheUpdate
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::Init(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMDocument *aDocument)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Make sure the service has been initialized
|
||||
nsOfflineCacheUpdateService* service =
|
||||
nsOfflineCacheUpdateService::EnsureService();
|
||||
if (!service)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LOG(("OfflineCacheUpdateChild::Init [%p]", this));
|
||||
|
||||
// Only http and https applications are supported.
|
||||
PRBool match;
|
||||
rv = aManifestURI->SchemeIs("http", &match);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!match) {
|
||||
rv = aManifestURI->SchemeIs("https", &match);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!match)
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
mManifestURI = aManifestURI;
|
||||
|
||||
rv = mManifestURI->GetAsciiHost(mUpdateDomain);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mDocumentURI = aDocumentURI;
|
||||
|
||||
mState = STATE_INITIALIZED;
|
||||
|
||||
if (aDocument)
|
||||
SetDocument(aDocument);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::InitPartial(nsIURI *aManifestURI,
|
||||
const nsACString& clientID,
|
||||
nsIURI *aDocumentURI)
|
||||
{
|
||||
NS_NOTREACHED("Not expected to do partial offline cache updates"
|
||||
" on the child process");
|
||||
// For now leaving this method, we may discover we need it.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::GetUpdateDomain(nsACString &aUpdateDomain)
|
||||
{
|
||||
NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
aUpdateDomain = mUpdateDomain;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::GetStatus(PRUint16 *aStatus)
|
||||
{
|
||||
switch (mState) {
|
||||
case STATE_CHECKING :
|
||||
*aStatus = nsIDOMOfflineResourceList::CHECKING;
|
||||
return NS_OK;
|
||||
case STATE_DOWNLOADING :
|
||||
*aStatus = nsIDOMOfflineResourceList::DOWNLOADING;
|
||||
return NS_OK;
|
||||
default :
|
||||
*aStatus = nsIDOMOfflineResourceList::IDLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::GetPartial(PRBool *aPartial)
|
||||
{
|
||||
*aPartial = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::GetManifestURI(nsIURI **aManifestURI)
|
||||
{
|
||||
NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
NS_IF_ADDREF(*aManifestURI = mManifestURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::GetSucceeded(PRBool *aSucceeded)
|
||||
{
|
||||
NS_ENSURE_TRUE(mState == STATE_FINISHED, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
*aSucceeded = mSucceeded;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::GetIsUpgrade(PRBool *aIsUpgrade)
|
||||
{
|
||||
NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
*aIsUpgrade = mIsUpgrade;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::AddDynamicURI(nsIURI *aURI)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::AddObserver(nsIOfflineCacheUpdateObserver *aObserver,
|
||||
PRBool aHoldWeak)
|
||||
{
|
||||
LOG(("OfflineCacheUpdateChild::AddObserver [%p]", this));
|
||||
|
||||
NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (aHoldWeak) {
|
||||
nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(aObserver);
|
||||
mWeakObservers.AppendObject(weakRef);
|
||||
} else {
|
||||
mObservers.AppendObject(aObserver);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::RemoveObserver(nsIOfflineCacheUpdateObserver *aObserver)
|
||||
{
|
||||
LOG(("OfflineCacheUpdateChild::RemoveObserver [%p]", this));
|
||||
|
||||
NS_ENSURE_TRUE(mState >= STATE_INITIALIZED, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
for (PRInt32 i = 0; i < mWeakObservers.Count(); i++) {
|
||||
nsCOMPtr<nsIOfflineCacheUpdateObserver> observer =
|
||||
do_QueryReferent(mWeakObservers[i]);
|
||||
if (observer == aObserver) {
|
||||
mWeakObservers.RemoveObjectAt(i);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
for (PRInt32 i = 0; i < mObservers.Count(); i++) {
|
||||
if (mObservers[i] == aObserver) {
|
||||
mObservers.RemoveObjectAt(i);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateChild::Schedule()
|
||||
{
|
||||
LOG(("OfflineCacheUpdateChild::Schedule [%p]", this));
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
NS_ASSERTION(mWindow, "Window must be provided to the offline cache update child");
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow =
|
||||
do_QueryInterface(mWindow);
|
||||
mWindow = nsnull;
|
||||
|
||||
nsIDocShell *docshell = piWindow->GetDocShell();
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(docshell);
|
||||
if (!item) {
|
||||
NS_WARNING("doc shell tree item is null");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||
item->GetTreeOwner(getter_AddRefs(owner));
|
||||
|
||||
nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
|
||||
if (!tabchild) {
|
||||
NS_WARNING("tab is null");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// because owner implements nsITabChild, we can assume that it is
|
||||
// the one and only TabChild.
|
||||
mozilla::dom::TabChild* child = static_cast<mozilla::dom::TabChild*>(tabchild.get());
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
LOG(("Calling offline-cache-update-added"));
|
||||
observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
|
||||
"offline-cache-update-added",
|
||||
nsnull);
|
||||
LOG(("Done offline-cache-update-added"));
|
||||
}
|
||||
|
||||
// mDocument is non-null if both:
|
||||
// 1. this update was initiated by a document that referred a manifest
|
||||
// 2. the document has not already been loaded from the application cache
|
||||
// This tells the update to cache this document even in case the manifest
|
||||
// has not been changed since the last fetch.
|
||||
// See also nsOfflineCacheUpdate::ScheduleImplicit.
|
||||
bool stickDocument = mDocument != nsnull;
|
||||
|
||||
// Need to addref ourself here, because the IPC stack doesn't hold
|
||||
// a reference to us. Will be released in RecvFinish() that identifies
|
||||
// the work has been done.
|
||||
child->SendPOfflineCacheUpdateConstructor(this,
|
||||
IPC::URI(mManifestURI),
|
||||
IPC::URI(mDocumentURI),
|
||||
mClientID,
|
||||
stickDocument);
|
||||
|
||||
mIPCActivated = PR_TRUE;
|
||||
this->AddRef();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
OfflineCacheUpdateChild::RecvAssociateDocuments(const nsCString &cacheGroupId,
|
||||
const nsCString &cacheClientId)
|
||||
{
|
||||
LOG(("OfflineCacheUpdateChild::RecvAssociateDocuments [%p, cache=%s]", this, cacheClientId.get()));
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIApplicationCache> cache =
|
||||
do_CreateInstance(NS_APPLICATIONCACHE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return true;
|
||||
|
||||
cache->InitAsHandle(cacheGroupId, cacheClientId);
|
||||
|
||||
if (mDocument) {
|
||||
AssociateDocument(mDocument, cache);
|
||||
}
|
||||
|
||||
nsCOMArray<nsIOfflineCacheUpdateObserver> observers;
|
||||
rv = GatherObservers(observers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRInt32 i = 0; i < observers.Count(); i++)
|
||||
observers[i]->ApplicationCacheAvailable(cache);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
OfflineCacheUpdateChild::RecvNotifyStateEvent(const PRUint32 &event)
|
||||
{
|
||||
LOG(("OfflineCacheUpdateChild::RecvNotifyStateEvent [%p]", this));
|
||||
|
||||
// Convert the public observer state to our internal state
|
||||
switch (event) {
|
||||
case nsIOfflineCacheUpdateObserver::STATE_CHECKING:
|
||||
mState = STATE_CHECKING;
|
||||
break;
|
||||
|
||||
case nsIOfflineCacheUpdateObserver::STATE_DOWNLOADING:
|
||||
mState = STATE_DOWNLOADING;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMArray<nsIOfflineCacheUpdateObserver> observers;
|
||||
nsresult rv = GatherObservers(observers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRInt32 i = 0; i < observers.Count(); i++)
|
||||
observers[i]->UpdateStateChanged(this, event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
OfflineCacheUpdateChild::RecvFinish(const bool &succeeded,
|
||||
const bool &isUpgrade)
|
||||
{
|
||||
LOG(("OfflineCacheUpdateChild::RecvFinish [%p]", this));
|
||||
|
||||
nsRefPtr<OfflineCacheUpdateChild> kungFuDeathGrip(this);
|
||||
|
||||
mState = STATE_FINISHED;
|
||||
mSucceeded = succeeded;
|
||||
mIsUpgrade = isUpgrade;
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
LOG(("Calling offline-cache-update-completed"));
|
||||
observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
|
||||
"offline-cache-update-completed",
|
||||
nsnull);
|
||||
LOG(("Done offline-cache-update-completed"));
|
||||
}
|
||||
|
||||
// This is by contract the last notification from the parent, release
|
||||
// us now. This is corresponding to AddRef in Schedule().
|
||||
this->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsOfflineCacheUpdateChild_h
|
||||
#define nsOfflineCacheUpdateChild_h
|
||||
|
||||
#include "mozilla/docshell/POfflineCacheUpdateChild.h"
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace docshell {
|
||||
|
||||
class OfflineCacheUpdateChild : public nsIOfflineCacheUpdate
|
||||
, public POfflineCacheUpdateChild
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOFFLINECACHEUPDATE
|
||||
|
||||
virtual bool
|
||||
RecvNotifyStateEvent(const PRUint32& stateEvent);
|
||||
|
||||
virtual bool
|
||||
RecvAssociateDocuments(
|
||||
const nsCString& cacheGroupId,
|
||||
const nsCString& cacheClientId);
|
||||
|
||||
virtual bool
|
||||
RecvFinish(const bool& succeded,
|
||||
const bool& isUpgrade);
|
||||
|
||||
OfflineCacheUpdateChild(nsIDOMWindow* aWindow);
|
||||
~OfflineCacheUpdateChild();
|
||||
|
||||
void SetDocument(nsIDOMDocument *aDocument);
|
||||
|
||||
private:
|
||||
nsresult AssociateDocument(nsIDOMDocument *aDocument,
|
||||
nsIApplicationCache *aApplicationCache);
|
||||
nsresult GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers);
|
||||
nsresult Finish();
|
||||
|
||||
void RefcountHitZero();
|
||||
|
||||
enum {
|
||||
STATE_UNINITIALIZED,
|
||||
STATE_INITIALIZED,
|
||||
STATE_CHECKING,
|
||||
STATE_DOWNLOADING,
|
||||
STATE_CANCELLED,
|
||||
STATE_FINISHED
|
||||
} mState;
|
||||
|
||||
PRPackedBool mIsUpgrade;
|
||||
PRPackedBool mSucceeded;
|
||||
PRPackedBool mIPCActivated;
|
||||
|
||||
nsCString mUpdateDomain;
|
||||
nsCOMPtr<nsIURI> mManifestURI;
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
|
||||
nsCString mClientID;
|
||||
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
|
||||
/* Clients watching this update for changes */
|
||||
nsCOMArray<nsIWeakReference> mWeakObservers;
|
||||
nsCOMArray<nsIOfflineCacheUpdateObserver> mObservers;
|
||||
|
||||
/* Document that requested this update */
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
|
||||
/* Keep reference to the window that owns this update to call the
|
||||
parent offline cache update construcor */
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,234 @@
|
|||
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "OfflineCacheUpdateGlue.h"
|
||||
#include "nsOfflineCacheUpdate.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#include "nsIApplicationCache.h"
|
||||
#include "nsIApplicationCacheChannel.h"
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// To enable logging (see prlog.h for full details):
|
||||
//
|
||||
// set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
|
||||
// set NSPR_LOG_FILE=offlineupdate.log
|
||||
//
|
||||
// this enables PR_LOG_ALWAYS level information and places all output in
|
||||
// the file offlineupdate.log
|
||||
//
|
||||
extern PRLogModuleInfo *gOfflineCacheUpdateLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
|
||||
#define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
|
||||
|
||||
namespace mozilla {
|
||||
namespace docshell {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OfflineCacheUpdateGlue::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS3(OfflineCacheUpdateGlue,
|
||||
nsIOfflineCacheUpdate,
|
||||
nsIOfflineCacheUpdateObserver,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OfflineCacheUpdateGlue <public>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
OfflineCacheUpdateGlue::OfflineCacheUpdateGlue()
|
||||
{
|
||||
LOG(("OfflineCacheUpdateGlue::OfflineCacheUpdateGlue [%p]", this));
|
||||
}
|
||||
|
||||
OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue()
|
||||
{
|
||||
LOG(("OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue [%p]", this));
|
||||
}
|
||||
|
||||
nsIOfflineCacheUpdate*
|
||||
OfflineCacheUpdateGlue::EnsureUpdate()
|
||||
{
|
||||
if (!mUpdate) {
|
||||
mUpdate = new nsOfflineCacheUpdate();
|
||||
LOG(("OfflineCacheUpdateGlue [%p] is using update [%p]", this, mUpdate.get()));
|
||||
}
|
||||
|
||||
return mUpdate;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateGlue::Schedule()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
LOG(("Calling offline-cache-update-added"));
|
||||
observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
|
||||
"offline-cache-update-added",
|
||||
nsnull);
|
||||
LOG(("Done offline-cache-update-added"));
|
||||
}
|
||||
|
||||
if (!EnsureUpdate())
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Do not use weak reference, we must survive!
|
||||
mUpdate->AddObserver(this, PR_FALSE);
|
||||
|
||||
return mUpdate->Schedule();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMDocument *aDocument)
|
||||
{
|
||||
if (!EnsureUpdate())
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
mDocumentURI = aDocumentURI;
|
||||
|
||||
if (aDocument)
|
||||
SetDocument(aDocument);
|
||||
|
||||
return mUpdate->Init(aManifestURI, aDocumentURI, nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
OfflineCacheUpdateGlue::SetDocument(nsIDOMDocument *aDocument)
|
||||
{
|
||||
// The design is one document for one cache update on the content process.
|
||||
NS_ASSERTION(!mDocument,
|
||||
"Setting more then a single document on an instance of OfflineCacheUpdateGlue");
|
||||
|
||||
LOG(("Document %p added to update glue %p", aDocument, this));
|
||||
|
||||
// Add document only if it was not loaded from an offline cache.
|
||||
// If it were loaded from an offline cache then it has already
|
||||
// been associated with it and must not be again cached as
|
||||
// implicit (which are the reasons we collect documents here).
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
|
||||
if (!document)
|
||||
return;
|
||||
|
||||
nsIChannel* channel = document->GetChannel();
|
||||
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
|
||||
do_QueryInterface(channel);
|
||||
if (!appCacheChannel)
|
||||
return;
|
||||
|
||||
PRBool loadedFromAppCache;
|
||||
appCacheChannel->GetLoadedFromApplicationCache(&loadedFromAppCache);
|
||||
if (loadedFromAppCache)
|
||||
return;
|
||||
|
||||
if (EnsureUpdate()) {
|
||||
mUpdate->StickDocument(mDocumentURI);
|
||||
}
|
||||
|
||||
mDocument = aDocument;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateGlue::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, PRUint32 state)
|
||||
{
|
||||
if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) {
|
||||
LOG(("OfflineCacheUpdateGlue got STATE_FINISHED [%p]", this));
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
LOG(("Calling offline-cache-update-completed"));
|
||||
observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
|
||||
"offline-cache-update-completed",
|
||||
nsnull);
|
||||
LOG(("Done offline-cache-update-completed"));
|
||||
}
|
||||
|
||||
aUpdate->RemoveObserver(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateGlue::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache)
|
||||
{
|
||||
NS_ENSURE_ARG(aApplicationCache);
|
||||
|
||||
// Check that the document that requested this update was
|
||||
// previously associated with an application cache. If not, it
|
||||
// should be associated with the new one.
|
||||
nsCOMPtr<nsIApplicationCacheContainer> container =
|
||||
do_QueryInterface(mDocument);
|
||||
if (!container)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIApplicationCache> existingCache;
|
||||
nsresult rv = container->GetApplicationCache(getter_AddRefs(existingCache));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!existingCache) {
|
||||
#if defined(PR_LOGGING)
|
||||
if (LOG_ENABLED()) {
|
||||
nsCAutoString clientID;
|
||||
if (aApplicationCache) {
|
||||
aApplicationCache->GetClientID(clientID);
|
||||
}
|
||||
LOG(("Update %p: associating app cache %s to document %p",
|
||||
this, clientID.get(), mDocument));
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = container->SetApplicationCache(aApplicationCache);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsOfflineCacheUpdateGlue_h
|
||||
#define nsOfflineCacheUpdateGlue_h
|
||||
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsOfflineCacheUpdate;
|
||||
|
||||
namespace mozilla {
|
||||
namespace docshell {
|
||||
|
||||
// Like FORWARD_SAFE except methods:
|
||||
// Schedule
|
||||
// Init
|
||||
#define NS_ADJUSTED_FORWARD_NSIOFFLINECACHEUPDATE(_to) \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetStatus(PRUint16 *aStatus) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetStatus(aStatus); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetPartial(PRBool *aPartial) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetPartial(aPartial); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetIsUpgrade(PRBool *aIsUpgrade) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetIsUpgrade(aIsUpgrade); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetUpdateDomain(nsACString & aUpdateDomain) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetUpdateDomain(aUpdateDomain); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetManifestURI(nsIURI **aManifestURI) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetManifestURI(aManifestURI); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSucceeded(PRBool *aSucceeded) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetSucceeded(aSucceeded); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD InitPartial(nsIURI *aManifestURI, const nsACString & aClientID, nsIURI *aDocumentURI) { return !_to ? NS_ERROR_NULL_POINTER : _to->InitPartial(aManifestURI, aClientID, aDocumentURI); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD AddDynamicURI(nsIURI *aURI) { return !_to ? NS_ERROR_NULL_POINTER : _to->AddDynamicURI(aURI); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD AddObserver(nsIOfflineCacheUpdateObserver *aObserver, PRBool aHoldWeak) { return !_to ? NS_ERROR_NULL_POINTER : _to->AddObserver(aObserver, aHoldWeak); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD RemoveObserver(nsIOfflineCacheUpdateObserver *aObserver) { return !_to ? NS_ERROR_NULL_POINTER : _to->RemoveObserver(aObserver); }
|
||||
|
||||
class OfflineCacheUpdateGlue : public nsSupportsWeakReference
|
||||
, public nsIOfflineCacheUpdate
|
||||
, public nsIOfflineCacheUpdateObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
private:
|
||||
nsIOfflineCacheUpdate* EnsureUpdate();
|
||||
|
||||
public:
|
||||
NS_ADJUSTED_FORWARD_NSIOFFLINECACHEUPDATE(EnsureUpdate())
|
||||
NS_SCRIPTABLE NS_IMETHOD Schedule(void);
|
||||
NS_SCRIPTABLE NS_IMETHOD Init(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMDocument *aDocument);
|
||||
|
||||
NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
|
||||
|
||||
OfflineCacheUpdateGlue();
|
||||
~OfflineCacheUpdateGlue();
|
||||
|
||||
void SetDocument(nsIDOMDocument *aDocument);
|
||||
|
||||
private:
|
||||
nsRefPtr<nsOfflineCacheUpdate> mUpdate;
|
||||
|
||||
/* Document that requested this update */
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,169 @@
|
|||
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "OfflineCacheUpdateParent.h"
|
||||
#include "nsOfflineCacheUpdate.h"
|
||||
#include "nsIApplicationCache.h"
|
||||
|
||||
static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nsnull;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// To enable logging (see prlog.h for full details):
|
||||
//
|
||||
// set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
|
||||
// set NSPR_LOG_FILE=offlineupdate.log
|
||||
//
|
||||
// this enables PR_LOG_ALWAYS level information and places all output in
|
||||
// the file offlineupdate.log
|
||||
//
|
||||
extern PRLogModuleInfo *gOfflineCacheUpdateLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
|
||||
#define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
|
||||
|
||||
namespace mozilla {
|
||||
namespace docshell {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OfflineCacheUpdateParent::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS1(OfflineCacheUpdateParent,
|
||||
nsIOfflineCacheUpdateObserver)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OfflineCacheUpdateParent <public>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
OfflineCacheUpdateParent::OfflineCacheUpdateParent()
|
||||
{
|
||||
// Make sure the service has been initialized
|
||||
nsOfflineCacheUpdateService* service =
|
||||
nsOfflineCacheUpdateService::EnsureService();
|
||||
if (!service)
|
||||
return;
|
||||
|
||||
LOG(("OfflineCacheUpdateParent::OfflineCacheUpdateParent [%p]", this));
|
||||
}
|
||||
|
||||
OfflineCacheUpdateParent::~OfflineCacheUpdateParent()
|
||||
{
|
||||
LOG(("OfflineCacheUpdateParent::~OfflineCacheUpdateParent [%p]", this));
|
||||
}
|
||||
|
||||
nsresult
|
||||
OfflineCacheUpdateParent::Schedule(const URI& aManifestURI,
|
||||
const URI& aDocumentURI,
|
||||
const nsCString& aClientID,
|
||||
const bool& stickDocument)
|
||||
{
|
||||
LOG(("OfflineCacheUpdateParent::RecvSchedule [%p]", this));
|
||||
|
||||
nsRefPtr<nsOfflineCacheUpdate> update;
|
||||
nsCOMPtr<nsIURI> manifestURI(aManifestURI);
|
||||
nsCOMPtr<nsIURI> documentURI(aDocumentURI);
|
||||
|
||||
nsOfflineCacheUpdateService* service =
|
||||
nsOfflineCacheUpdateService::EnsureService();
|
||||
if (!service)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
service->FindUpdate(manifestURI, documentURI, getter_AddRefs(update));
|
||||
if (!update) {
|
||||
update = new nsOfflineCacheUpdate();
|
||||
|
||||
nsresult rv;
|
||||
// Leave aDocument argument null. Only glues and children keep
|
||||
// document instances.
|
||||
rv = update->Init(manifestURI, documentURI, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = update->Schedule();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
update->AddObserver(this, PR_FALSE);
|
||||
|
||||
if (stickDocument) {
|
||||
nsCOMPtr<nsIURI> stickURI;
|
||||
documentURI->Clone(getter_AddRefs(stickURI));
|
||||
update->StickDocument(stickURI);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateParent::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, PRUint32 state)
|
||||
{
|
||||
LOG(("OfflineCacheUpdateParent::StateEvent [%p]", this));
|
||||
|
||||
SendNotifyStateEvent(state);
|
||||
|
||||
if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) {
|
||||
// Tell the child the particulars after the update has finished.
|
||||
// Sending the Finish event will release the child side of the protocol
|
||||
// and notify "offline-cache-update-completed" on the child process.
|
||||
PRBool isUpgrade;
|
||||
aUpdate->GetIsUpgrade(&isUpgrade);
|
||||
PRBool succeeded;
|
||||
aUpdate->GetSucceeded(&succeeded);
|
||||
|
||||
SendFinish(succeeded, isUpgrade);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineCacheUpdateParent::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache)
|
||||
{
|
||||
NS_ENSURE_ARG(aApplicationCache);
|
||||
|
||||
nsCString cacheClientId;
|
||||
aApplicationCache->GetClientID(cacheClientId);
|
||||
nsCString cacheGroupId;
|
||||
aApplicationCache->GetGroupID(cacheGroupId);
|
||||
|
||||
SendAssociateDocuments(cacheGroupId, cacheClientId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // docshell
|
||||
} // mozilla
|
|
@ -0,0 +1,72 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsOfflineCacheUpdateParent_h
|
||||
#define nsOfflineCacheUpdateParent_h
|
||||
|
||||
#include "mozilla/docshell/POfflineCacheUpdateParent.h"
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace docshell {
|
||||
|
||||
class OfflineCacheUpdateParent : public POfflineCacheUpdateParent
|
||||
, public nsIOfflineCacheUpdateObserver
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
|
||||
|
||||
nsresult
|
||||
Schedule(const URI& manifestURI,
|
||||
const URI& documentURI,
|
||||
const nsCString& clientID,
|
||||
const bool& stickDocument);
|
||||
|
||||
OfflineCacheUpdateParent();
|
||||
~OfflineCacheUpdateParent();
|
||||
|
||||
private:
|
||||
void RefcountHitZero();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
|
||||
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
include protocol PBrowser;
|
||||
|
||||
include "mozilla/net/NeckoMessageUtils.h";
|
||||
|
||||
using IPC::URI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace docshell {
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
protocol POfflineCacheUpdate
|
||||
{
|
||||
manager PBrowser;
|
||||
|
||||
parent:
|
||||
__delete__();
|
||||
|
||||
child:
|
||||
NotifyStateEvent(PRUint32 stateEvent);
|
||||
AssociateDocuments(nsCString cacheGroupId, nsCString cacheClientId);
|
||||
Finish(bool succeded, bool isUpgrate);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla Firefox.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# The Mozilla Foundation <http://www.mozilla.org/>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Jason Duell
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
IPDLSRCS = \
|
||||
POfflineCacheUpdate.ipdl \
|
||||
$(NULL)
|
||||
|
|
@ -39,76 +39,44 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIDOMWindow;
|
||||
interface nsIDOMNode;
|
||||
interface nsIDOMDocument;
|
||||
interface nsIDOMLoadStatus;
|
||||
interface nsIOfflineCacheUpdate;
|
||||
interface nsIPrincipal;
|
||||
interface nsIPrefBranch;
|
||||
interface nsIApplicationCache;
|
||||
|
||||
[scriptable, uuid(a28abeaf-a0b4-4440-b2fe-bc78249710ea)]
|
||||
[scriptable, uuid(47360d57-8ef4-4a5d-8865-1a27a739ad1a)]
|
||||
interface nsIOfflineCacheUpdateObserver : nsISupports {
|
||||
/**
|
||||
* There was an error updating the cache.
|
||||
*
|
||||
* @param aUpdate
|
||||
* The nsIOfflineCacheUpdate being processed.
|
||||
*/
|
||||
void error(in nsIOfflineCacheUpdate aUpdate);
|
||||
const unsigned long STATE_ERROR = 1;
|
||||
const unsigned long STATE_CHECKING = 2;
|
||||
const unsigned long STATE_NOUPDATE = 3;
|
||||
const unsigned long STATE_OBSOLETE = 4;
|
||||
const unsigned long STATE_DOWNLOADING = 5;
|
||||
const unsigned long STATE_ITEMSTARTED = 6;
|
||||
const unsigned long STATE_ITEMCOMPLETED = 7;
|
||||
const unsigned long STATE_FINISHED = 10;
|
||||
|
||||
/**
|
||||
* The manifest is being checked for updates
|
||||
* aUpdate has changed its state.
|
||||
*
|
||||
* @param aUpdate
|
||||
* The nsIOfflineCacheUpdate being processed.
|
||||
* @param event
|
||||
* See enumeration above
|
||||
*/
|
||||
void checking(in nsIOfflineCacheUpdate aUpdate);
|
||||
void updateStateChanged(in nsIOfflineCacheUpdate aUpdate, in PRUint32 state);
|
||||
|
||||
/**
|
||||
* No update was necessary.
|
||||
* Informs the observer about an application being available to associate.
|
||||
*
|
||||
* @param aUpdate
|
||||
* The nsIOfflineCacheUpdate being processed.
|
||||
* @param applicationCache
|
||||
* The application cache instance that has been created or found by the
|
||||
* update to associate with
|
||||
*/
|
||||
void noUpdate(in nsIOfflineCacheUpdate aUpdate);
|
||||
|
||||
/**
|
||||
* The cache group is now obsolete.
|
||||
*
|
||||
* @param aUpdate
|
||||
* The nsIOfflineCacheUpdate being processed.
|
||||
*/
|
||||
void obsolete(in nsIOfflineCacheUpdate aUpdate);
|
||||
|
||||
/**
|
||||
* Starting to download resources
|
||||
*
|
||||
* @param aUpdate
|
||||
* The nsIOfflineCacheUpdate being processed.
|
||||
*/
|
||||
void downloading(in nsIOfflineCacheUpdate aUpdate);
|
||||
|
||||
/**
|
||||
* An item has started downloading.
|
||||
*
|
||||
* @param aUpdate
|
||||
* The nsIOfflineCacheUpdate being processed.
|
||||
* @param aItem
|
||||
* load status for the item that is being downloaded.
|
||||
*/
|
||||
void itemStarted(in nsIOfflineCacheUpdate aUpdate,
|
||||
in nsIDOMLoadStatus aItem);
|
||||
|
||||
/**
|
||||
* An item has finished loading.
|
||||
*
|
||||
* @param aUpdate
|
||||
* The nsIOfflineCacheUpdate being processed.
|
||||
* @param aItem
|
||||
* load status for the item that completed.
|
||||
*/
|
||||
void itemCompleted(in nsIOfflineCacheUpdate aUpdate,
|
||||
in nsIDOMLoadStatus aItem);
|
||||
void applicationCacheAvailable(in nsIApplicationCache applicationCache);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -125,7 +93,7 @@ interface nsIOfflineCacheUpdateObserver : nsISupports {
|
|||
* load its items one by one, sending itemCompleted() to any registered
|
||||
* observers.
|
||||
*/
|
||||
[scriptable, uuid(877261bb-b952-4d27-847e-859bdd47c0ec)]
|
||||
[scriptable, uuid(24605d81-8cf9-4021-8575-7f39aacbf31a)]
|
||||
interface nsIOfflineCacheUpdate : nsISupports {
|
||||
/**
|
||||
* Fetch the status of the running update. This will return a value
|
||||
|
@ -169,7 +137,7 @@ interface nsIOfflineCacheUpdate : nsISupports {
|
|||
* @param aDocumentURI
|
||||
* The page that is requesting the update.
|
||||
*/
|
||||
void init(in nsIURI aManifestURI, in nsIURI aDocumentURI);
|
||||
void init(in nsIURI aManifestURI, in nsIURI aDocumentURI, in nsIDOMDocument aDocument);
|
||||
|
||||
/**
|
||||
* Initialize the update for partial processing.
|
||||
|
@ -200,12 +168,6 @@ interface nsIOfflineCacheUpdate : nsISupports {
|
|||
*/
|
||||
void schedule();
|
||||
|
||||
/**
|
||||
* Access to the list of items in the update.
|
||||
*/
|
||||
readonly attribute unsigned long count;
|
||||
nsIDOMLoadStatus item(in unsigned long index);
|
||||
|
||||
/**
|
||||
* Observe loads that are added to the update.
|
||||
*
|
||||
|
@ -254,7 +216,8 @@ interface nsIOfflineCacheUpdateService : nsISupports {
|
|||
* Otherwise a new update will be scheduled.
|
||||
*/
|
||||
nsIOfflineCacheUpdate scheduleUpdate(in nsIURI aManifestURI,
|
||||
in nsIURI aDocumentURI);
|
||||
in nsIURI aDocumentURI,
|
||||
in nsIDOMWindow aWindow);
|
||||
|
||||
/**
|
||||
* Schedule a cache update for a manifest when the document finishes
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -211,11 +211,13 @@ public:
|
|||
};
|
||||
|
||||
class nsOfflineCacheUpdate : public nsIOfflineCacheUpdate
|
||||
, public nsIOfflineCacheUpdateObserver
|
||||
, public nsOfflineCacheUpdateOwner
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOFFLINECACHEUPDATE
|
||||
NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
|
||||
|
||||
nsOfflineCacheUpdate();
|
||||
~nsOfflineCacheUpdate();
|
||||
|
@ -230,7 +232,7 @@ public:
|
|||
void LoadCompleted();
|
||||
void ManifestCheckCompleted(nsresult aStatus,
|
||||
const nsCString &aManifestHash);
|
||||
void AddDocument(nsIDOMDocument *aDocument);
|
||||
void StickDocument(nsIURI *aDocumentURI);
|
||||
|
||||
void SetOwner(nsOfflineCacheUpdateOwner *aOwner);
|
||||
|
||||
|
@ -247,19 +249,13 @@ private:
|
|||
// specified namespaces will be added.
|
||||
nsresult AddExistingItems(PRUint32 aType,
|
||||
nsTArray<nsCString>* namespaceFilter = nsnull);
|
||||
nsresult ScheduleImplicit();
|
||||
nsresult AssociateDocuments(nsIApplicationCache* cache);
|
||||
|
||||
nsresult GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers);
|
||||
nsresult NotifyError();
|
||||
nsresult NotifyChecking();
|
||||
nsresult NotifyNoUpdate();
|
||||
nsresult NotifyObsolete();
|
||||
nsresult NotifyDownloading();
|
||||
nsresult NotifyStarted(nsOfflineCacheUpdateItem *aItem);
|
||||
nsresult NotifyCompleted(nsOfflineCacheUpdateItem *aItem);
|
||||
nsresult AssociateDocument(nsIDOMDocument *aDocument,
|
||||
nsIApplicationCache *aApplicationCache);
|
||||
nsresult ScheduleImplicit();
|
||||
nsresult NotifyState(PRUint32 state);
|
||||
nsresult Finish();
|
||||
nsresult FinishNoNotify();
|
||||
|
||||
enum {
|
||||
STATE_UNINITIALIZED,
|
||||
|
@ -279,7 +275,6 @@ private:
|
|||
|
||||
nsCString mUpdateDomain;
|
||||
nsCOMPtr<nsIURI> mManifestURI;
|
||||
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
|
||||
nsCString mClientID;
|
||||
|
@ -299,7 +294,7 @@ private:
|
|||
nsCOMArray<nsIOfflineCacheUpdateObserver> mObservers;
|
||||
|
||||
/* Documents that requested this update */
|
||||
nsCOMArray<nsIDOMDocument> mDocuments;
|
||||
nsCOMArray<nsIURI> mDocumentURIs;
|
||||
|
||||
/* Reschedule count. When an update is rescheduled due to
|
||||
* mismatched manifests, the reschedule count will be increased. */
|
||||
|
@ -323,10 +318,15 @@ public:
|
|||
|
||||
nsresult Init();
|
||||
|
||||
nsresult Schedule(nsOfflineCacheUpdate *aUpdate);
|
||||
nsresult ScheduleUpdate(nsOfflineCacheUpdate *aUpdate);
|
||||
nsresult FindUpdate(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsOfflineCacheUpdate **aUpdate);
|
||||
|
||||
nsresult Schedule(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMDocument *aDocument,
|
||||
nsIDOMWindow* aWindow,
|
||||
nsIOfflineCacheUpdate **aUpdate);
|
||||
|
||||
virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);
|
||||
|
|
|
@ -0,0 +1,612 @@
|
|||
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
#include "OfflineCacheUpdateChild.h"
|
||||
#include "OfflineCacheUpdateParent.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#endif
|
||||
#include "OfflineCacheUpdateGlue.h"
|
||||
#include "nsOfflineCacheUpdate.h"
|
||||
|
||||
#include "nsCPrefetchService.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
#include "nsIApplicationCacheChannel.h"
|
||||
#include "nsIApplicationCacheService.h"
|
||||
#include "nsICache.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsICacheSession.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMOfflineResourceList.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsICryptoHash.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nsnull;
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
typedef mozilla::docshell::OfflineCacheUpdateParent OfflineCacheUpdateParent;
|
||||
typedef mozilla::docshell::OfflineCacheUpdateChild OfflineCacheUpdateChild;
|
||||
#endif
|
||||
typedef mozilla::docshell::OfflineCacheUpdateGlue OfflineCacheUpdateGlue;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// To enable logging (see prlog.h for full details):
|
||||
//
|
||||
// set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
|
||||
// set NSPR_LOG_FILE=offlineupdate.log
|
||||
//
|
||||
// this enables PR_LOG_ALWAYS level information and places all output in
|
||||
// the file offlineupdate.log
|
||||
//
|
||||
PRLogModuleInfo *gOfflineCacheUpdateLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gOfflineCacheUpdateLog, 4, args)
|
||||
#define LOG_ENABLED() PR_LOG_TEST(gOfflineCacheUpdateLog, 4)
|
||||
|
||||
class AutoFreeArray {
|
||||
public:
|
||||
AutoFreeArray(PRUint32 count, char **values)
|
||||
: mCount(count), mValues(values) {};
|
||||
~AutoFreeArray() { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mValues); }
|
||||
private:
|
||||
PRUint32 mCount;
|
||||
char **mValues;
|
||||
};
|
||||
|
||||
static nsresult
|
||||
DropReferenceFromURL(nsIURI * aURI)
|
||||
{
|
||||
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
|
||||
if (url) {
|
||||
nsresult rv = url->SetRef(EmptyCString());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCachePendingUpdate
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsOfflineCachePendingUpdate : public nsIWebProgressListener
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
nsOfflineCachePendingUpdate(nsOfflineCacheUpdateService *aService,
|
||||
nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMDocument *aDocument)
|
||||
: mService(aService)
|
||||
, mManifestURI(aManifestURI)
|
||||
, mDocumentURI(aDocumentURI)
|
||||
{
|
||||
mDocument = do_GetWeakReference(aDocument);
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsOfflineCacheUpdateService> mService;
|
||||
nsCOMPtr<nsIURI> mManifestURI;
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIWeakReference> mDocument;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsOfflineCachePendingUpdate,
|
||||
nsIWebProgressListener,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCacheUpdateService::nsIWebProgressListener
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCachePendingUpdate::OnProgressChange(nsIWebProgress *aProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 curSelfProgress,
|
||||
PRInt32 maxSelfProgress,
|
||||
PRInt32 curTotalProgress,
|
||||
PRInt32 maxTotalProgress)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCachePendingUpdate::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRUint32 progressStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> updateDoc = do_QueryReferent(mDocument);
|
||||
if (!updateDoc) {
|
||||
// The document that scheduled this update has gone away,
|
||||
// we don't need to listen anymore.
|
||||
aWebProgress->RemoveProgressListener(this);
|
||||
NS_RELEASE_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!(progressStateFlags & STATE_STOP)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window;
|
||||
aWebProgress->GetDOMWindow(getter_AddRefs(window));
|
||||
if (!window) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> progressDoc;
|
||||
window->GetDocument(getter_AddRefs(progressDoc));
|
||||
if (!progressDoc) return NS_OK;
|
||||
|
||||
if (!SameCOMIdentity(progressDoc, updateDoc)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOG(("nsOfflineCachePendingUpdate::OnStateChange [%p, doc=%p]",
|
||||
this, progressDoc.get()));
|
||||
|
||||
// Only schedule the update if the document loaded successfully
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
nsCOMPtr<nsIOfflineCacheUpdate> update;
|
||||
mService->Schedule(mManifestURI, mDocumentURI,
|
||||
updateDoc, window, getter_AddRefs(update));
|
||||
}
|
||||
|
||||
aWebProgress->RemoveProgressListener(this);
|
||||
NS_RELEASE_THIS();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCachePendingUpdate::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCachePendingUpdate::OnStatusChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar* aMessage)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCachePendingUpdate::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRUint32 state)
|
||||
{
|
||||
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCacheUpdateService::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS3(nsOfflineCacheUpdateService,
|
||||
nsIOfflineCacheUpdateService,
|
||||
nsIObserver,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCacheUpdateService <public>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsOfflineCacheUpdateService::nsOfflineCacheUpdateService()
|
||||
: mDisabled(PR_FALSE)
|
||||
, mUpdateRunning(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsOfflineCacheUpdateService::~nsOfflineCacheUpdateService()
|
||||
{
|
||||
gOfflineCacheUpdateService = nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheUpdateService::Init()
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gOfflineCacheUpdateLog)
|
||||
gOfflineCacheUpdateLog = PR_NewLogModule("nsOfflineCacheUpdate");
|
||||
#endif
|
||||
|
||||
// Observe xpcom-shutdown event
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (!observerService)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = observerService->AddObserver(this,
|
||||
NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
gOfflineCacheUpdateService = this;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsOfflineCacheUpdateService *
|
||||
nsOfflineCacheUpdateService::GetInstance()
|
||||
{
|
||||
if (!gOfflineCacheUpdateService) {
|
||||
gOfflineCacheUpdateService = new nsOfflineCacheUpdateService();
|
||||
if (!gOfflineCacheUpdateService)
|
||||
return nsnull;
|
||||
NS_ADDREF(gOfflineCacheUpdateService);
|
||||
nsresult rv = gOfflineCacheUpdateService->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(gOfflineCacheUpdateService);
|
||||
return nsnull;
|
||||
}
|
||||
return gOfflineCacheUpdateService;
|
||||
}
|
||||
|
||||
NS_ADDREF(gOfflineCacheUpdateService);
|
||||
|
||||
return gOfflineCacheUpdateService;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsOfflineCacheUpdateService *
|
||||
nsOfflineCacheUpdateService::EnsureService()
|
||||
{
|
||||
if (!gOfflineCacheUpdateService) {
|
||||
// Make the service manager hold a long-lived reference to the service
|
||||
nsCOMPtr<nsIOfflineCacheUpdateService> service =
|
||||
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
|
||||
}
|
||||
|
||||
return gOfflineCacheUpdateService;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheUpdateService::ScheduleUpdate(nsOfflineCacheUpdate *aUpdate)
|
||||
{
|
||||
LOG(("nsOfflineCacheUpdateService::Schedule [%p, update=%p]",
|
||||
this, aUpdate));
|
||||
|
||||
aUpdate->SetOwner(this);
|
||||
|
||||
mUpdates.AppendElement(aUpdate);
|
||||
ProcessNextUpdate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateService::ScheduleOnDocumentStop(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMDocument *aDocument)
|
||||
{
|
||||
LOG(("nsOfflineCacheUpdateService::ScheduleOnDocumentStop [%p, manifestURI=%p, documentURI=%p doc=%p]",
|
||||
this, aManifestURI, aDocumentURI, aDocument));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
|
||||
nsCOMPtr<nsISupports> container = doc->GetContainer();
|
||||
nsCOMPtr<nsIWebProgress> progress = do_QueryInterface(container);
|
||||
NS_ENSURE_TRUE(progress, NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Proceed with cache update
|
||||
nsRefPtr<nsOfflineCachePendingUpdate> update =
|
||||
new nsOfflineCachePendingUpdate(this, aManifestURI,
|
||||
aDocumentURI, aDocument);
|
||||
NS_ENSURE_TRUE(update, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = progress->AddProgressListener
|
||||
(update, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The update will release when it has scheduled itself.
|
||||
update.forget();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheUpdateService::UpdateFinished(nsOfflineCacheUpdate *aUpdate)
|
||||
{
|
||||
LOG(("nsOfflineCacheUpdateService::UpdateFinished [%p, update=%p]",
|
||||
this, aUpdate));
|
||||
|
||||
NS_ASSERTION(mUpdates.Length() > 0 &&
|
||||
mUpdates[0] == aUpdate, "Unknown update completed");
|
||||
|
||||
// keep this item alive until we're done notifying observers
|
||||
nsRefPtr<nsOfflineCacheUpdate> update = mUpdates[0];
|
||||
mUpdates.RemoveElementAt(0);
|
||||
mUpdateRunning = PR_FALSE;
|
||||
|
||||
ProcessNextUpdate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCacheUpdateService <private>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheUpdateService::ProcessNextUpdate()
|
||||
{
|
||||
LOG(("nsOfflineCacheUpdateService::ProcessNextUpdate [%p, num=%d]",
|
||||
this, mUpdates.Length()));
|
||||
|
||||
if (mDisabled)
|
||||
return NS_ERROR_ABORT;
|
||||
|
||||
if (mUpdateRunning)
|
||||
return NS_OK;
|
||||
|
||||
if (mUpdates.Length() > 0) {
|
||||
mUpdateRunning = PR_TRUE;
|
||||
return mUpdates[0]->Begin();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCacheUpdateService::nsIOfflineCacheUpdateService
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateService::GetNumUpdates(PRUint32 *aNumUpdates)
|
||||
{
|
||||
LOG(("nsOfflineCacheUpdateService::GetNumUpdates [%p]", this));
|
||||
|
||||
*aNumUpdates = mUpdates.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateService::GetUpdate(PRUint32 aIndex,
|
||||
nsIOfflineCacheUpdate **aUpdate)
|
||||
{
|
||||
LOG(("nsOfflineCacheUpdateService::GetUpdate [%p, %d]", this, aIndex));
|
||||
|
||||
if (aIndex < mUpdates.Length()) {
|
||||
NS_ADDREF(*aUpdate = mUpdates[aIndex]);
|
||||
} else {
|
||||
*aUpdate = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheUpdateService::FindUpdate(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsOfflineCacheUpdate **aUpdate)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsRefPtr<nsOfflineCacheUpdate> update;
|
||||
for (PRUint32 i = 0; i < mUpdates.Length(); i++) {
|
||||
update = mUpdates[i];
|
||||
|
||||
PRBool partial;
|
||||
rv = update->GetPartial(&partial);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (partial) {
|
||||
// Partial updates aren't considered
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> manifestURI;
|
||||
update->GetManifestURI(getter_AddRefs(manifestURI));
|
||||
if (manifestURI) {
|
||||
PRBool equals;
|
||||
rv = manifestURI->Equals(aManifestURI, &equals);
|
||||
if (equals) {
|
||||
update.swap(*aUpdate);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOfflineCacheUpdateService::Schedule(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMDocument *aDocument,
|
||||
nsIDOMWindow* aWindow,
|
||||
nsIOfflineCacheUpdate **aUpdate)
|
||||
{
|
||||
nsCOMPtr<nsIOfflineCacheUpdate> update;
|
||||
#ifdef MOZ_IPC
|
||||
if (GeckoProcessType_Default != XRE_GetProcessType()) {
|
||||
update = new OfflineCacheUpdateChild(aWindow);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
update = new OfflineCacheUpdateGlue();
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = update->Init(aManifestURI, aDocumentURI, aDocument);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = update->Schedule();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aUpdate = update);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateService::ScheduleUpdate(nsIURI *aManifestURI,
|
||||
nsIURI *aDocumentURI,
|
||||
nsIDOMWindow *aWindow,
|
||||
nsIOfflineCacheUpdate **aUpdate)
|
||||
{
|
||||
return Schedule(aManifestURI, aDocumentURI, nsnull, aWindow, aUpdate);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCacheUpdateService::nsIObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateService::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
if (mUpdates.Length() > 0)
|
||||
mUpdates[0]->Cancel();
|
||||
mDisabled = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsOfflineCacheUpdateService::nsIOfflineCacheUpdateService
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateService::OfflineAppAllowed(nsIPrincipal *aPrincipal,
|
||||
nsIPrefBranch *aPrefBranch,
|
||||
PRBool *aAllowed)
|
||||
{
|
||||
nsCOMPtr<nsIURI> codebaseURI;
|
||||
nsresult rv = aPrincipal->GetURI(getter_AddRefs(codebaseURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return OfflineAppAllowedForURI(codebaseURI, aPrefBranch, aAllowed);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateService::OfflineAppAllowedForURI(nsIURI *aURI,
|
||||
nsIPrefBranch *aPrefBranch,
|
||||
PRBool *aAllowed)
|
||||
{
|
||||
*aAllowed = PR_FALSE;
|
||||
if (!aURI)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
|
||||
if (!innerURI)
|
||||
return NS_OK;
|
||||
|
||||
// only http and https applications can use offline APIs.
|
||||
PRBool match;
|
||||
nsresult rv = innerURI->SchemeIs("http", &match);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!match) {
|
||||
rv = innerURI->SchemeIs("https", &match);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!match) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
if (!permissionManager) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 perm;
|
||||
permissionManager->TestExactPermission(innerURI, "offline-app", &perm);
|
||||
|
||||
if (perm == nsIPermissionManager::UNKNOWN_ACTION) {
|
||||
nsCOMPtr<nsIPrefBranch> branch = aPrefBranch;
|
||||
if (!branch) {
|
||||
branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
}
|
||||
if (branch) {
|
||||
rv = branch->GetBoolPref("offline-apps.allow_by_default", aAllowed);
|
||||
if (NS_FAILED(rv)) {
|
||||
*aAllowed = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (perm == nsIPermissionManager::DENY_ACTION) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aAllowed = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
Загрузка…
Ссылка в новой задаче