Bug 794663 - Allow downloading appcache for a specific appid/browserflag, r=jduell

This commit is contained in:
Honza Bambas 2012-10-26 13:02:47 +02:00
parent edba2799c8
commit 4d04a9cc72
9 changed files with 122 additions and 47 deletions

View File

@ -82,6 +82,8 @@ OfflineCacheUpdateChild::OfflineCacheUpdateChild(nsIDOMWindow* aWindow)
: mState(STATE_UNINITIALIZED)
, mIsUpgrade(false)
, mIPCActivated(false)
, mInBrowser(false)
, mAppID(NECKO_NO_APP_ID)
, mWindow(aWindow)
, mByteProgress(0)
{
@ -183,7 +185,8 @@ OfflineCacheUpdateChild::Init(nsIURI *aManifestURI,
nsIURI *aDocumentURI,
nsIDOMDocument *aDocument,
nsIFile *aCustomProfileDir,
nsILoadContext *aLoadContext)
uint32_t aAppID,
bool aInBrowser)
{
nsresult rv;
@ -224,7 +227,8 @@ OfflineCacheUpdateChild::Init(nsIURI *aManifestURI,
if (aDocument)
SetDocument(aDocument);
mLoadContext = aLoadContext;
mAppID = aAppID;
mInBrowser = aInBrowser;
return NS_OK;
}
@ -427,19 +431,11 @@ OfflineCacheUpdateChild::Schedule()
// See also nsOfflineCacheUpdate::ScheduleImplicit.
bool stickDocument = mDocument != nullptr;
// Carry load context to the parent
bool isInBrowserElement = false;
uint32_t appId = NECKO_NO_APP_ID;
if (mLoadContext) {
mLoadContext->GetIsInBrowserElement(&isInBrowserElement);
mLoadContext->GetAppId(&appId);
}
// 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, manifestURI, documentURI,
isInBrowserElement, appId,
mInBrowser, mAppID,
stickDocument);
mIPCActivated = true;

View File

@ -73,7 +73,9 @@ private:
nsCOMPtr<nsIURI> mDocumentURI;
nsCOMPtr<nsIObserverService> mObserverService;
nsCOMPtr<nsILoadContext> mLoadContext;
uint32_t mAppID;
bool mInBrowser;
/* Clients watching this update for changes */
nsCOMArray<nsIWeakReference> mWeakObservers;

View File

@ -93,7 +93,8 @@ OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI,
nsIURI *aDocumentURI,
nsIDOMDocument *aDocument,
nsIFile *aCustomProfileDir,
nsILoadContext *aLoadContext)
uint32_t aAppID,
bool aInBrowser)
{
if (!EnsureUpdate())
return NS_ERROR_NULL_POINTER;
@ -103,7 +104,7 @@ OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI,
if (aDocument)
SetDocument(aDocument);
return mUpdate->Init(aManifestURI, aDocumentURI, nullptr, aCustomProfileDir, aLoadContext);
return mUpdate->Init(aManifestURI, aDocumentURI, nullptr, aCustomProfileDir, aAppID, aInBrowser);
}
void

View File

@ -53,7 +53,8 @@ public:
nsIURI *aDocumentURI,
nsIDOMDocument *aDocument,
nsIFile *aCustomProfileDir,
nsILoadContext *aLoadContext);
uint32_t aAppID,
bool aInBrowser);
NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER

View File

@ -75,10 +75,6 @@ OfflineCacheUpdateParent::Schedule(const URIParams& aManifestURI,
{
LOG(("OfflineCacheUpdateParent::RecvSchedule [%p]", this));
// Load context members
mIsInBrowserElement = isInBrowserElement;
mAppId = appId;
nsRefPtr<nsOfflineCacheUpdate> update;
nsCOMPtr<nsIURI> manifestURI = DeserializeURI(aManifestURI);
if (!manifestURI)
@ -104,13 +100,15 @@ OfflineCacheUpdateParent::Schedule(const URIParams& aManifestURI,
if (!NS_SecurityCompareURIs(manifestURI, documentURI, false))
return NS_ERROR_DOM_SECURITY_ERR;
service->FindUpdate(manifestURI, this, getter_AddRefs(update));
service->FindUpdate(manifestURI, appId, isInBrowserElement,
getter_AddRefs(update));
if (!update) {
update = new nsOfflineCacheUpdate();
// Leave aDocument argument null. Only glues and children keep
// document instances.
rv = update->Init(manifestURI, documentURI, nullptr, nullptr, this);
rv = update->Init(manifestURI, documentURI, nullptr, nullptr,
appId, isInBrowserElement);
NS_ENSURE_SUCCESS(rv, rv);
rv = update->Schedule();

View File

@ -15,7 +15,6 @@ interface nsIPrincipal;
interface nsIPrefBranch;
interface nsIApplicationCache;
interface nsIFile;
interface nsILoadContext;
interface nsIObserver;
[scriptable, uuid(47360d57-8ef4-4a5d-8865-1a27a739ad1a)]
@ -64,7 +63,7 @@ interface nsIOfflineCacheUpdateObserver : nsISupports {
* load its items one by one, sending itemCompleted() to any registered
* observers.
*/
[scriptable, uuid(91d356fa-4eaf-4de2-9870-bb92854cccfe)]
[scriptable, uuid(91b94446-5d91-4089-bed7-edfab25824a7)]
interface nsIOfflineCacheUpdate : nsISupports {
/**
* Fetch the status of the running update. This will return a value
@ -110,7 +109,8 @@ interface nsIOfflineCacheUpdate : nsISupports {
*/
void init(in nsIURI aManifestURI, in nsIURI aDocumentURI, in nsIDOMDocument aDocument,
[optional] in nsIFile aCustomProfileDir,
[optional] in nsILoadContext aLoadContext);
[optional] in unsigned long aAppId,
[optional] in boolean aInBrowser);
/**
* Initialize the update for partial processing.
@ -190,7 +190,7 @@ interface nsIOfflineCacheUpdate : nsISupports {
readonly attribute uint64_t byteProgress;
};
[scriptable, uuid(9ff7f81f-114a-4876-ad1b-f3910418e4a6)]
[scriptable, uuid(cf362a31-4166-4994-8443-b68704ecdcc0)]
interface nsIOfflineCacheUpdateService : nsISupports {
/**
* Constants for the offline-app permission.
@ -229,6 +229,17 @@ interface nsIOfflineCacheUpdateService : nsISupports {
in nsIURI aDocumentURI,
in nsIFile aProfileDir);
/**
* Schedule a cache update for a given offline manifest using app cache
* bound to the given appID+inBrowser flag. If an existing update is
* scheduled or running, that update will be returned. Otherwise a new
* update will be scheduled.
*/
nsIOfflineCacheUpdate scheduleAppUpdate(in nsIURI aManifestURI,
in nsIURI aDocumentURI,
in unsigned long aAppID,
in boolean aInBrowser);
/**
* Schedule a cache update for a manifest when the document finishes
* loading.

View File

@ -1171,6 +1171,8 @@ nsOfflineCacheUpdate::nsOfflineCacheUpdate()
, mOnlyCheckUpdate(false)
, mSucceeded(true)
, mObsolete(false)
, mAppID(NECKO_NO_APP_ID)
, mInBrowser(false)
, mItemsInProgress(0)
, mRescheduleCount(0)
, mPinnedEntryRetriesCount(0)
@ -1231,7 +1233,8 @@ nsOfflineCacheUpdate::Init(nsIURI *aManifestURI,
nsIURI *aDocumentURI,
nsIDOMDocument *aDocument,
nsIFile *aCustomProfileDir,
nsILoadContext *aLoadContext)
uint32_t aAppID,
bool aInBrowser)
{
nsresult rv;
@ -1273,9 +1276,9 @@ nsOfflineCacheUpdate::Init(nsIURI *aManifestURI,
mCustomProfileDir = aCustomProfileDir;
}
else {
rv = cacheService->BuildGroupID(aManifestURI,
aLoadContext,
mGroupID);
rv = cacheService->BuildGroupIDForApp(aManifestURI,
aAppID, aInBrowser,
mGroupID);
NS_ENSURE_SUCCESS(rv, rv);
rv = cacheService->GetActiveCache(mGroupID,
@ -1292,7 +1295,8 @@ nsOfflineCacheUpdate::Init(nsIURI *aManifestURI,
&mPinned);
NS_ENSURE_SUCCESS(rv, rv);
mLoadContext = aLoadContext;
mAppID = aAppID;
mInBrowser = aInBrowser;
mState = STATE_INITIALIZED;
return NS_OK;
@ -1697,7 +1701,7 @@ nsOfflineCacheUpdate::ManifestCheckCompleted(nsresult aStatus,
// Leave aDocument argument null. Only glues and children keep
// document instances.
newUpdate->Init(mManifestURI, mDocumentURI, nullptr,
mCustomProfileDir, mLoadContext);
mCustomProfileDir, mAppID, mInBrowser);
// In a rare case the manifest will not be modified on the next refetch
// transfer all master document URIs to the new update to ensure that

View File

@ -37,6 +37,7 @@ class nsOfflineCacheUpdate;
class nsICacheEntryDescriptor;
class nsIUTF8StringEnumerator;
class nsILoadContext;
class nsOfflineCacheUpdateItem : public nsIDOMLoadStatus
, public nsIStreamListener
@ -264,7 +265,10 @@ private:
nsCOMPtr<nsIURI> mManifestURI;
nsCOMPtr<nsIURI> mDocumentURI;
nsCOMPtr<nsIFile> mCustomProfileDir;
nsCOMPtr<nsILoadContext> mLoadContext;
uint32_t mAppID;
bool mInBrowser;
nsCOMPtr<nsIObserver> mUpdateAvailableObserver;
nsCOMPtr<nsIApplicationCache> mApplicationCache;
@ -317,7 +321,8 @@ public:
nsresult ScheduleUpdate(nsOfflineCacheUpdate *aUpdate);
nsresult FindUpdate(nsIURI *aManifestURI,
nsILoadContext *aLoadContext,
uint32_t aAppID,
bool aInBrowser,
nsOfflineCacheUpdate **aUpdate);
nsresult Schedule(nsIURI *aManifestURI,
@ -325,6 +330,8 @@ public:
nsIDOMDocument *aDocument,
nsIDOMWindow* aWindow,
nsIFile* aCustomProfileDir,
uint32_t aAppID,
bool aInBrowser,
nsIOfflineCacheUpdate **aUpdate);
virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate);

View File

@ -81,6 +81,39 @@ private:
char **mValues;
};
namespace { // anon
nsresult
GetAppIDAndInBrowserFromWindow(nsIDOMWindow *aWindow,
uint32_t *aAppId,
bool *aInBrowser)
{
*aAppId = NECKO_NO_APP_ID;
*aInBrowser = false;
if (!aWindow) {
return NS_OK;
}
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
if (!loadContext) {
return NS_OK;
}
nsresult rv;
rv = loadContext->GetAppId(aAppId);
NS_ENSURE_SUCCESS(rv, rv);
rv = loadContext->GetIsInBrowserElement(aInBrowser);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
} // anon
//-----------------------------------------------------------------------------
// nsOfflineCachePendingUpdate
//-----------------------------------------------------------------------------
@ -166,9 +199,16 @@ nsOfflineCachePendingUpdate::OnStateChange(nsIWebProgress* aWebProgress,
// Only schedule the update if the document loaded successfully
if (NS_SUCCEEDED(aStatus)) {
// Get extended origin attributes
uint32_t appId;
bool isInBrowserElement;
nsresult rv = GetAppIDAndInBrowserFromWindow(window, &appId, &isInBrowserElement);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIOfflineCacheUpdate> update;
mService->Schedule(mManifestURI, mDocumentURI,
updateDoc, window, nullptr, getter_AddRefs(update));
updateDoc, window, nullptr,
appId, isInBrowserElement, getter_AddRefs(update));
}
aWebProgress->RemoveProgressListener(this);
@ -405,7 +445,8 @@ nsOfflineCacheUpdateService::GetUpdate(uint32_t aIndex,
nsresult
nsOfflineCacheUpdateService::FindUpdate(nsIURI *aManifestURI,
nsILoadContext *aLoadContext,
uint32_t aAppID,
bool aInBrowser,
nsOfflineCacheUpdate **aUpdate)
{
nsresult rv;
@ -415,9 +456,9 @@ nsOfflineCacheUpdateService::FindUpdate(nsIURI *aManifestURI,
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString groupID;
rv = cacheService->BuildGroupID(aManifestURI,
aLoadContext,
groupID);
rv = cacheService->BuildGroupIDForApp(aManifestURI,
aAppID, aInBrowser,
groupID);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsOfflineCacheUpdate> update;
@ -448,6 +489,8 @@ nsOfflineCacheUpdateService::Schedule(nsIURI *aManifestURI,
nsIDOMDocument *aDocument,
nsIDOMWindow* aWindow,
nsIFile* aCustomProfileDir,
uint32_t aAppID,
bool aInBrowser,
nsIOfflineCacheUpdate **aUpdate)
{
nsCOMPtr<nsIOfflineCacheUpdate> update;
@ -460,14 +503,8 @@ nsOfflineCacheUpdateService::Schedule(nsIURI *aManifestURI,
nsresult rv;
nsCOMPtr<nsILoadContext> loadContext;
if (aWindow) {
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
loadContext = do_QueryInterface(webNav);
}
rv = update->Init(aManifestURI, aDocumentURI, aDocument,
aCustomProfileDir, loadContext);
aCustomProfileDir, aAppID, aInBrowser);
NS_ENSURE_SUCCESS(rv, rv);
rv = update->Schedule();
@ -484,7 +521,14 @@ nsOfflineCacheUpdateService::ScheduleUpdate(nsIURI *aManifestURI,
nsIDOMWindow *aWindow,
nsIOfflineCacheUpdate **aUpdate)
{
return Schedule(aManifestURI, aDocumentURI, nullptr, aWindow, nullptr, aUpdate);
// Get extended origin attributes
uint32_t appId;
bool isInBrowser;
nsresult rv = GetAppIDAndInBrowserFromWindow(aWindow, &appId, &isInBrowser);
NS_ENSURE_SUCCESS(rv, rv);
return Schedule(aManifestURI, aDocumentURI, nullptr, aWindow, nullptr,
appId, isInBrowser, aUpdate);
}
NS_IMETHODIMP
@ -496,7 +540,18 @@ nsOfflineCacheUpdateService::ScheduleCustomProfileUpdate(nsIURI *aManifestURI,
// The profile directory is mandatory
NS_ENSURE_ARG(aProfileDir);
return Schedule(aManifestURI, aDocumentURI, nullptr, nullptr, aProfileDir, aUpdate);
return Schedule(aManifestURI, aDocumentURI, nullptr, nullptr, aProfileDir,
NECKO_NO_APP_ID, false, aUpdate);
}
NS_IMETHODIMP
nsOfflineCacheUpdateService::ScheduleAppUpdate(nsIURI *aManifestURI,
nsIURI *aDocumentURI,
uint32_t aAppID, bool aInBrowser,
nsIOfflineCacheUpdate **aUpdate)
{
return Schedule(aManifestURI, aDocumentURI, nullptr, nullptr, nullptr,
aAppID, aInBrowser, aUpdate);
}
NS_IMETHODIMP nsOfflineCacheUpdateService::CheckForUpdate(nsIURI *aManifestURI,