mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1155153 - about:serviceworkers should work in e10s mode, r=nsm, r=bholley
This commit is contained in:
parent
fd40bf471d
commit
4283f0af5f
@ -17,44 +17,109 @@
|
||||
|
||||
#include "mozilla/dom/CSPDictionariesBinding.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/URLSearchParams.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using dom::URLSearchParams;
|
||||
|
||||
void
|
||||
OriginAttributes::CreateSuffix(nsACString& aStr) const
|
||||
{
|
||||
aStr.Truncate();
|
||||
MOZ_RELEASE_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
int attrCount = 0;
|
||||
|
||||
nsRefPtr<URLSearchParams> usp = new URLSearchParams();
|
||||
nsAutoString value;
|
||||
|
||||
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
aStr.Append(attrCount++ ? "&appId=" : "!appId=");
|
||||
aStr.AppendInt(mAppId);
|
||||
value.AppendInt(mAppId);
|
||||
usp->Set(NS_LITERAL_STRING("appId"), value);
|
||||
}
|
||||
|
||||
if (mInBrowser) {
|
||||
aStr.Append(attrCount++ ? "&inBrowser=1" : "!inBrowser=1");
|
||||
usp->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
|
||||
}
|
||||
|
||||
aStr.Truncate();
|
||||
|
||||
usp->Serialize(value);
|
||||
if (!value.IsEmpty()) {
|
||||
aStr.AppendLiteral("!");
|
||||
aStr.Append(NS_ConvertUTF16toUTF8(value));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::Serialize(nsIObjectOutputStream* aStream) const
|
||||
namespace {
|
||||
|
||||
class MOZ_STACK_CLASS PopulateFromSuffixIterator final
|
||||
: public URLSearchParams::ForEachIterator
|
||||
{
|
||||
aStream->Write32(mAppId);
|
||||
aStream->WriteBoolean(mInBrowser);
|
||||
public:
|
||||
explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
|
||||
: mOriginAttributes(aOriginAttributes)
|
||||
{
|
||||
MOZ_ASSERT(aOriginAttributes);
|
||||
}
|
||||
|
||||
bool URLSearchParamsIterator(const nsString& aName,
|
||||
const nsString& aValue) override
|
||||
{
|
||||
if (aName.EqualsLiteral("appId")) {
|
||||
nsresult rv;
|
||||
mOriginAttributes->mAppId = aValue.ToInteger(&rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mOriginAttributes->mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("inBrowser")) {
|
||||
if (!aValue.EqualsLiteral("1")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOriginAttributes->mInBrowser = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// No other attributes are supported.
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
OriginAttributes* mOriginAttributes;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
bool
|
||||
OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
|
||||
{
|
||||
if (aStr.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aStr[0] != '!') {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<URLSearchParams> usp = new URLSearchParams();
|
||||
usp->ParseInput(Substring(aStr, 1, aStr.Length() - 1), nullptr);
|
||||
|
||||
PopulateFromSuffixIterator iterator(this);
|
||||
return usp->ForEach(iterator);
|
||||
}
|
||||
|
||||
nsresult
|
||||
OriginAttributes::Deserialize(nsIObjectInputStream* aStream)
|
||||
{
|
||||
nsresult rv = aStream->Read32(&mAppId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
BasePrincipal::BasePrincipal()
|
||||
{}
|
||||
|
||||
rv = aStream->ReadBoolean(&mInBrowser);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
BasePrincipal::~BasePrincipal()
|
||||
{}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetOrigin(nsACString& aOrigin)
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "mozilla/dom/SystemDictionariesBinding.h"
|
||||
|
||||
class nsIContentSecurityPolicy;
|
||||
class nsIObjectOutputStream;
|
||||
class nsIObjectInputStream;
|
||||
|
||||
@ -38,13 +39,11 @@ public:
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
// Serializes non-default values into the suffix format, i.e.
|
||||
// Serializes/Deserializes non-default values into the suffix format, i.e.
|
||||
// |!key1=value1&key2=value2|. If there are no non-default attributes, this
|
||||
// returns an empty string.
|
||||
void CreateSuffix(nsACString& aStr) const;
|
||||
|
||||
void Serialize(nsIObjectOutputStream* aStream) const;
|
||||
nsresult Deserialize(nsIObjectInputStream* aStream);
|
||||
bool PopulateFromSuffix(const nsACString& aStr);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -57,7 +56,7 @@ public:
|
||||
class BasePrincipal : public nsJSPrincipals
|
||||
{
|
||||
public:
|
||||
BasePrincipal() {}
|
||||
BasePrincipal();
|
||||
|
||||
enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain};
|
||||
bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
|
||||
@ -93,7 +92,7 @@ public:
|
||||
bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; }
|
||||
|
||||
protected:
|
||||
virtual ~BasePrincipal() {}
|
||||
virtual ~BasePrincipal();
|
||||
|
||||
virtual nsresult GetOriginInternal(nsACString& aOrigin) = 0;
|
||||
virtual bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsider) = 0;
|
||||
|
@ -82,7 +82,7 @@ nsNullPrincipal::GetHashValue(uint32_t *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetURI(nsIURI** aURI)
|
||||
{
|
||||
return NS_EnsureSafeToReturn(mURI, aURI);
|
||||
@ -160,13 +160,25 @@ nsNullPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
// that the Init() method has already been invoked by the time we deserialize.
|
||||
// This is in contrast to nsPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
|
||||
// in which case ::Read needs to invoke Init().
|
||||
return mOriginAttributes.Deserialize(aStream);
|
||||
nsAutoCString suffix;
|
||||
nsresult rv = aStream->ReadCString(suffix);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool ok = mOriginAttributes.PopulateFromSuffix(suffix);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
OriginAttributesRef().Serialize(aStream);
|
||||
nsAutoCString suffix;
|
||||
OriginAttributesRef().CreateSuffix(suffix);
|
||||
|
||||
nsresult rv = aStream->WriteStringZ(suffix.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@
|
||||
class nsIURI;
|
||||
|
||||
#define NS_NULLPRINCIPAL_CID \
|
||||
{ 0xa0bd8b42, 0xf6bf, 0x4fb9, \
|
||||
{ 0x93, 0x42, 0x90, 0xbf, 0xc9, 0xb7, 0xa1, 0xab } }
|
||||
{ 0xe502ffb8, 0x5d95, 0x48e8, \
|
||||
{ 0x82, 0x3c, 0x0d, 0x29, 0xd8, 0x3a, 0x59, 0x33 } }
|
||||
#define NS_NULLPRINCIPAL_CONTRACTID "@mozilla.org/nullprincipal;1"
|
||||
|
||||
#define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
|
||||
|
@ -360,10 +360,14 @@ nsPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
|
||||
domain = do_QueryInterface(supports);
|
||||
|
||||
OriginAttributes attrs;
|
||||
rv = attrs.Deserialize(aStream);
|
||||
nsAutoCString suffix;
|
||||
rv = aStream->ReadCString(suffix);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
OriginAttributes attrs;
|
||||
bool ok = attrs.PopulateFromSuffix(suffix);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -404,7 +408,11 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
return rv;
|
||||
}
|
||||
|
||||
OriginAttributesRef().Serialize(aStream);
|
||||
nsAutoCString suffix;
|
||||
OriginAttributesRef().CreateSuffix(suffix);
|
||||
|
||||
rv = aStream->WriteStringZ(suffix.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
|
||||
NS_GET_IID(nsIContentSecurityPolicy),
|
||||
|
@ -112,12 +112,12 @@ private:
|
||||
|
||||
#define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
|
||||
#define NS_PRINCIPAL_CID \
|
||||
{ 0x09b7e598, 0x490d, 0x423f, \
|
||||
{ 0xa8, 0xa6, 0x2e, 0x6c, 0x4e, 0xc8, 0x77, 0x50 }}
|
||||
{ 0xb7c8505e, 0xc56d, 0x4191, \
|
||||
{ 0xa1, 0x5e, 0x5d, 0xcb, 0x88, 0x9b, 0xa0, 0x94 }}
|
||||
|
||||
#define NS_EXPANDEDPRINCIPAL_CONTRACTID "@mozilla.org/expandedprincipal;1"
|
||||
#define NS_EXPANDEDPRINCIPAL_CID \
|
||||
{ 0xb33a3807, 0xb76c, 0x44e5, \
|
||||
{ 0xb9, 0x9d, 0x95, 0x7e, 0xe9, 0xba, 0x6e, 0x39 }}
|
||||
{ 0x38539471, 0x68cc, 0x4a6f, \
|
||||
{ 0x81, 0x20, 0xdb, 0xd5, 0x4a, 0x22, 0x0a, 0x13 }}
|
||||
|
||||
#endif // nsPrincipal_h__
|
||||
|
@ -105,6 +105,7 @@ static RedirEntry kRedirMap[] = {
|
||||
},
|
||||
{
|
||||
"serviceworkers", "chrome://global/content/aboutServiceWorkers.xhtml",
|
||||
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
|
||||
nsIAboutModule::ALLOW_SCRIPT
|
||||
},
|
||||
// about:srcdoc is unresolvable by specification. It is included here
|
||||
|
@ -27,6 +27,10 @@ public:
|
||||
virtual void URLSearchParamsUpdated(URLSearchParams* aFromThis) = 0;
|
||||
};
|
||||
|
||||
// This class is used in BasePrincipal and it's _extremely_ important that the
|
||||
// attributes are kept in the correct order. If this changes, please, update
|
||||
// BasePrincipal code.
|
||||
|
||||
class URLSearchParams final : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
@ -81,15 +85,24 @@ public:
|
||||
Serialize(aRetval);
|
||||
}
|
||||
|
||||
typedef void (*ParamFunc)(const nsString& aName, const nsString& aValue,
|
||||
void* aClosure);
|
||||
class ForEachIterator
|
||||
{
|
||||
public:
|
||||
virtual bool
|
||||
URLSearchParamsIterator(const nsString& aName, const nsString& aValue) = 0;
|
||||
};
|
||||
|
||||
void
|
||||
ForEach(ParamFunc aFunc, void* aClosure)
|
||||
bool
|
||||
ForEach(ForEachIterator& aIterator)
|
||||
{
|
||||
for (uint32_t i = 0; i < mSearchParams.Length(); ++i) {
|
||||
aFunc(mSearchParams[i].mKey, mSearchParams[i].mValue, aClosure);
|
||||
if (!aIterator.URLSearchParamsIterator(mSearchParams[i].mKey,
|
||||
mSearchParams[i].mValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -548,13 +548,26 @@ ExtractFromURLSearchParams(const URLSearchParams& aParams,
|
||||
return NS_NewStringInputStream(aStream, serialized);
|
||||
}
|
||||
|
||||
void
|
||||
FillFormData(const nsString& aName, const nsString& aValue, void* aFormData)
|
||||
class MOZ_STACK_CLASS FillFormIterator final
|
||||
: public URLSearchParams::ForEachIterator
|
||||
{
|
||||
MOZ_ASSERT(aFormData);
|
||||
nsFormData* fd = static_cast<nsFormData*>(aFormData);
|
||||
fd->Append(aName, aValue);
|
||||
}
|
||||
public:
|
||||
explicit FillFormIterator(nsFormData* aFormData)
|
||||
: mFormData(aFormData)
|
||||
{
|
||||
MOZ_ASSERT(aFormData);
|
||||
}
|
||||
|
||||
bool URLSearchParamsIterator(const nsString& aName,
|
||||
const nsString& aValue) override
|
||||
{
|
||||
mFormData->Append(aName, aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
nsFormData* mFormData;
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple multipart/form-data parser as defined in RFC 2388 and RFC 2046.
|
||||
@ -1591,7 +1604,10 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
|
||||
params->ParseInput(data, /* aObserver */ nullptr);
|
||||
|
||||
nsRefPtr<nsFormData> fd = new nsFormData(DerivedClass()->GetParentObject());
|
||||
params->ForEach(FillFormData, static_cast<void*>(fd));
|
||||
FillFormIterator iterator(fd);
|
||||
DebugOnly<bool> status = params->ForEach(iterator);
|
||||
MOZ_ASSERT(status);
|
||||
|
||||
localPromise->MaybeResolve(fd);
|
||||
} else {
|
||||
ErrorResult result;
|
||||
|
@ -33,7 +33,7 @@ interface nsIServiceWorkerInfo : nsISupports
|
||||
readonly attribute DOMString waitingCacheName;
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(d130fcbd-1afe-4dd9-b70d-08a4b2373af5)]
|
||||
[scriptable, builtinclass, uuid(5e112a42-df4c-4ae9-bc71-e6e681ab5f38)]
|
||||
interface nsIServiceWorkerManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -96,13 +96,6 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
*/
|
||||
[noscript] nsISupports GetDocumentController(in nsIDOMWindow aWindow);
|
||||
|
||||
/*
|
||||
* This implements the soft update algorithm.
|
||||
* XXXbaku this can be removed when bug 1155153 lands.
|
||||
*/
|
||||
[implicit_jscontext] void softUpdate(in jsval aOriginAttributes,
|
||||
in DOMString aScope);
|
||||
|
||||
/*
|
||||
* Clears ServiceWorker registrations from memory and disk for the specified
|
||||
* host.
|
||||
@ -122,10 +115,22 @@ interface nsIServiceWorkerManager : nsISupports
|
||||
// Testing
|
||||
DOMString getScopeForUrl(in nsIPrincipal aPrincipal, in DOMString aPath);
|
||||
|
||||
// This is meant to be used only by about:serviceworkers. It returns an array
|
||||
// of nsIServiceWorkerInfo.
|
||||
// Note: This is meant to be used only by about:serviceworkers.
|
||||
//It returns an array of nsIServiceWorkerInfo.
|
||||
nsIArray getAllRegistrations();
|
||||
|
||||
// Note: This is meant to be used only by about:serviceworkers.
|
||||
// It calls softUpdate() for each child process.
|
||||
[implicit_jscontext] void propagateSoftUpdate(in jsval aOriginAttributes,
|
||||
in DOMString aScope);
|
||||
|
||||
// Note: This is meant to be used only by about:serviceworkers.
|
||||
// It calls unregister() in each child process. The callback is used to
|
||||
// inform when unregister() is completed on the current process.
|
||||
void propagateUnregister(in nsIPrincipal aPrincipal,
|
||||
in nsIServiceWorkerUnregisterCallback aCallback,
|
||||
in DOMString aScope);
|
||||
|
||||
[implicit_jscontext] void sendPushEvent(in jsval aOriginAttributes,
|
||||
in ACString aScope,
|
||||
in DOMString aData);
|
||||
|
39
dom/workers/PServiceWorkerManager.ipdl
Normal file
39
dom/workers/PServiceWorkerManager.ipdl
Normal file
@ -0,0 +1,39 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
|
||||
include PBackgroundSharedTypes;
|
||||
include ServiceWorkerRegistrarTypes;
|
||||
|
||||
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
protocol PServiceWorkerManager
|
||||
{
|
||||
manager PBackground;
|
||||
|
||||
parent:
|
||||
Register(ServiceWorkerRegistrationData data);
|
||||
|
||||
Unregister(PrincipalInfo principalInfo, nsString scope);
|
||||
|
||||
PropagateSoftUpdate(OriginAttributes originAttributes,
|
||||
nsString scope);
|
||||
PropagateUnregister(PrincipalInfo principalInfo, nsString scope);
|
||||
|
||||
Shutdown();
|
||||
|
||||
child:
|
||||
NotifyRegister(ServiceWorkerRegistrationData data);
|
||||
NotifySoftUpdate(OriginAttributes originAttributes, nsString scope);
|
||||
NotifyUnregister(PrincipalInfo principalInfo, nsString scope);
|
||||
|
||||
__delete__();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
@ -54,6 +54,7 @@
|
||||
#include "ServiceWorker.h"
|
||||
#include "ServiceWorkerClient.h"
|
||||
#include "ServiceWorkerContainer.h"
|
||||
#include "ServiceWorkerManagerChild.h"
|
||||
#include "ServiceWorkerRegistrar.h"
|
||||
#include "ServiceWorkerRegistration.h"
|
||||
#include "ServiceWorkerScriptCache.h"
|
||||
@ -256,6 +257,28 @@ PopulateRegistrationData(nsIPrincipal* aPrincipal,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class TeardownRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit TeardownRunnable(ServiceWorkerManagerChild* aActor)
|
||||
: mActor(aActor)
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
mActor->SendShutdown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~TeardownRunnable() {}
|
||||
|
||||
nsRefPtr<ServiceWorkerManagerChild> mActor;
|
||||
};
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
NS_IMPL_ISUPPORTS0(ServiceWorkerJob)
|
||||
@ -360,6 +383,14 @@ ServiceWorkerManager::~ServiceWorkerManager()
|
||||
{
|
||||
// The map will assert if it is not empty when destroyed.
|
||||
mRegistrationInfos.Clear();
|
||||
|
||||
if (mActor) {
|
||||
mActor->ManagerShuttingDown();
|
||||
|
||||
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -685,6 +716,72 @@ GetRequiredScopeStringPrefix(nsIURI* aScriptURI, nsACString& aPrefix,
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class PropagateSoftUpdateRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
PropagateSoftUpdateRunnable(const OriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope)
|
||||
: mOriginAttributes(aOriginAttributes)
|
||||
, mScope(aScope)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
swm->PropagateSoftUpdate(mOriginAttributes,mScope);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~PropagateSoftUpdateRunnable()
|
||||
{}
|
||||
|
||||
const OriginAttributes mOriginAttributes;
|
||||
const nsString mScope;
|
||||
};
|
||||
|
||||
class PropagateUnregisterRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
PropagateUnregisterRunnable(nsIPrincipal* aPrincipal,
|
||||
nsIServiceWorkerUnregisterCallback* aCallback,
|
||||
const nsAString& aScope)
|
||||
: mPrincipal(aPrincipal)
|
||||
, mCallback(aCallback)
|
||||
, mScope(aScope)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
nsresult rv = swm->PropagateUnregister(mPrincipal, mCallback, mScope);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~PropagateUnregisterRunnable()
|
||||
{}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIServiceWorkerUnregisterCallback> mCallback;
|
||||
const nsString mScope;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class ServiceWorkerRegisterJob final : public ServiceWorkerJob,
|
||||
@ -2207,8 +2304,7 @@ private:
|
||||
}
|
||||
|
||||
MOZ_ASSERT(swm->mActor);
|
||||
swm->mActor->SendUnregisterServiceWorker(principalInfo,
|
||||
NS_ConvertUTF8toUTF16(mScope));
|
||||
swm->mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(mScope));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2431,6 +2527,39 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::LoadRegistration(
|
||||
const ServiceWorkerRegistrationData& aRegistration)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
PrincipalInfoToPrincipal(aRegistration.principal());
|
||||
if (!principal) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
GetRegistration(principal, aRegistration.scope());
|
||||
if (!registration) {
|
||||
registration = CreateNewRegistration(aRegistration.scope(), principal);
|
||||
} else if (registration->mScriptSpec == aRegistration.scriptSpec() &&
|
||||
!!registration->mActiveWorker == aRegistration.currentWorkerURL().IsEmpty()) {
|
||||
// No needs for updates.
|
||||
return;
|
||||
}
|
||||
|
||||
registration->mScriptSpec = aRegistration.scriptSpec();
|
||||
|
||||
const nsCString& currentWorkerURL = aRegistration.currentWorkerURL();
|
||||
if (!currentWorkerURL.IsEmpty()) {
|
||||
registration->mActiveWorker =
|
||||
new ServiceWorkerInfo(registration, currentWorkerURL,
|
||||
aRegistration.activeCacheName());
|
||||
registration->mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::LoadRegistrations(
|
||||
const nsTArray<ServiceWorkerRegistrationData>& aRegistrations)
|
||||
@ -2438,23 +2567,7 @@ ServiceWorkerManager::LoadRegistrations(
|
||||
AssertIsOnMainThread();
|
||||
|
||||
for (uint32_t i = 0, len = aRegistrations.Length(); i < len; ++i) {
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
PrincipalInfoToPrincipal(aRegistrations[i].principal());
|
||||
if (!principal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ServiceWorkerRegistrationInfo* registration =
|
||||
CreateNewRegistration(aRegistrations[i].scope(), principal);
|
||||
|
||||
registration->mScriptSpec = aRegistrations[i].scriptSpec();
|
||||
|
||||
const nsCString& currentWorkerURL = aRegistrations[i].currentWorkerURL();
|
||||
if (!currentWorkerURL.IsEmpty()) {
|
||||
registration->mActiveWorker =
|
||||
new ServiceWorkerInfo(registration, currentWorkerURL, aRegistrations[i].activeCacheName());
|
||||
registration->mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
||||
}
|
||||
LoadRegistration(aRegistrations[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2469,7 +2582,11 @@ ServiceWorkerManager::ActorCreated(mozilla::ipc::PBackgroundChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(!mActor);
|
||||
mActor = aActor;
|
||||
|
||||
PServiceWorkerManagerChild* actor =
|
||||
aActor->SendPServiceWorkerManagerConstructor();
|
||||
|
||||
mActor = static_cast<ServiceWorkerManagerChild*>(actor);
|
||||
|
||||
// Flush the pending requests.
|
||||
for (uint32_t i = 0, len = mPendingOperations.Length(); i < len; ++i) {
|
||||
@ -2511,7 +2628,7 @@ ServiceWorkerManager::StoreRegistration(
|
||||
return;
|
||||
}
|
||||
|
||||
mActor->SendRegisterServiceWorker(data);
|
||||
mActor->SendRegister(data);
|
||||
}
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||
@ -3453,24 +3570,6 @@ ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerReg
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::SoftUpdate(JS::Handle<JS::Value> aOriginAttributes,
|
||||
const nsAString& aScope, JSContext* aCx)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
OriginAttributes attrs;
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsAutoCString scopeKey;
|
||||
attrs.CreateSuffix(scopeKey);
|
||||
|
||||
SoftUpdate(scopeKey, NS_ConvertUTF16toUTF8(aScope));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::SoftUpdate(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aScope)
|
||||
@ -3486,6 +3585,15 @@ ServiceWorkerManager::SoftUpdate(nsIPrincipal* aPrincipal,
|
||||
SoftUpdate(scopeKey, aScope);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::SoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
const nsACString& aScope)
|
||||
{
|
||||
nsAutoCString scopeKey;
|
||||
aOriginAttributes.CreateSuffix(scopeKey);
|
||||
SoftUpdate(scopeKey, aScope);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::SoftUpdate(const nsACString& aScopeKey,
|
||||
const nsACString& aScope)
|
||||
@ -3775,6 +3883,10 @@ ServiceWorkerManager::CreateNewRegistration(const nsCString& aScope,
|
||||
nsCOMPtr<nsIURI> scopeURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), aScope, nullptr, nullptr);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsRefPtr<ServiceWorkerRegistrationInfo> tmp =
|
||||
GetRegistration(aPrincipal, aScope);
|
||||
MOZ_ASSERT(!tmp);
|
||||
#endif
|
||||
|
||||
ServiceWorkerRegistrationInfo* registration = new ServiceWorkerRegistrationInfo(aScope, aPrincipal);
|
||||
@ -3817,8 +3929,7 @@ ServiceWorkerManager::RemoveRegistrationInternal(ServiceWorkerRegistrationInfo*
|
||||
return;
|
||||
}
|
||||
|
||||
mActor->SendUnregisterServiceWorker(principalInfo,
|
||||
NS_ConvertUTF8toUTF16(aRegistration->mScope));
|
||||
mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(aRegistration->mScope));
|
||||
}
|
||||
|
||||
class ServiceWorkerDataInfo final : public nsIServiceWorkerInfo
|
||||
@ -3828,7 +3939,7 @@ public:
|
||||
NS_DECL_NSISERVICEWORKERINFO
|
||||
|
||||
static already_AddRefed<ServiceWorkerDataInfo>
|
||||
Create(const ServiceWorkerRegistrationData& aData);
|
||||
Create(const ServiceWorkerRegistrationInfo* aData);
|
||||
|
||||
private:
|
||||
ServiceWorkerDataInfo()
|
||||
@ -3844,6 +3955,7 @@ private:
|
||||
nsString mActiveCacheName;
|
||||
nsString mWaitingCacheName;
|
||||
};
|
||||
|
||||
void
|
||||
ServiceWorkerManager::RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
|
||||
{
|
||||
@ -3951,26 +4063,61 @@ UnregisterIfMatchesHostPerPrincipal(const nsACString& aKey,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
GetAllRegistrationsEnumerator(const nsACString& aScope,
|
||||
ServiceWorkerRegistrationInfo* aReg,
|
||||
void* aData)
|
||||
{
|
||||
nsIMutableArray* array = static_cast<nsIMutableArray*>(aData);
|
||||
MOZ_ASSERT(aReg);
|
||||
|
||||
if (aReg->mPendingUninstall) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerInfo> info = ServiceWorkerDataInfo::Create(aReg);
|
||||
if (NS_WARN_IF(!info)) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
array->AppendElement(info, false);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
GetAllRegistrationsPerPrincipalEnumerator(const nsACString& aKey,
|
||||
ServiceWorkerManager::RegistrationDataPerPrincipal* aData,
|
||||
void* aUserData)
|
||||
{
|
||||
aData->mInfos.EnumerateRead(GetAllRegistrationsEnumerator, aUserData);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NS_IMPL_ISUPPORTS(ServiceWorkerDataInfo, nsIServiceWorkerInfo)
|
||||
|
||||
/* static */ already_AddRefed<ServiceWorkerDataInfo>
|
||||
ServiceWorkerDataInfo::Create(const ServiceWorkerRegistrationData& aData)
|
||||
ServiceWorkerDataInfo::Create(const ServiceWorkerRegistrationInfo* aData)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
nsRefPtr<ServiceWorkerDataInfo> info = new ServiceWorkerDataInfo();
|
||||
|
||||
info->mPrincipal = PrincipalInfoToPrincipal(aData.principal());
|
||||
if (!info->mPrincipal) {
|
||||
return nullptr;
|
||||
info->mPrincipal = aData->mPrincipal;
|
||||
CopyUTF8toUTF16(aData->mScope, info->mScope);
|
||||
CopyUTF8toUTF16(aData->mScriptSpec, info->mScriptSpec);
|
||||
|
||||
if (aData->mActiveWorker) {
|
||||
CopyUTF8toUTF16(aData->mActiveWorker->ScriptSpec(),
|
||||
info->mCurrentWorkerURL);
|
||||
info->mActiveCacheName = aData->mActiveWorker->CacheName();
|
||||
}
|
||||
|
||||
CopyUTF8toUTF16(aData.scope(), info->mScope);
|
||||
CopyUTF8toUTF16(aData.scriptSpec(), info->mScriptSpec);
|
||||
CopyUTF8toUTF16(aData.currentWorkerURL(), info->mCurrentWorkerURL);
|
||||
info->mActiveCacheName = aData.activeCacheName();
|
||||
info->mWaitingCacheName = aData.waitingCacheName();
|
||||
if (aData->mWaitingWorker) {
|
||||
info->mWaitingCacheName = aData->mWaitingWorker->CacheName();
|
||||
}
|
||||
|
||||
return info.forget();
|
||||
}
|
||||
@ -4028,26 +4175,12 @@ ServiceWorkerManager::GetAllRegistrations(nsIArray** aResult)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsRefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
|
||||
MOZ_ASSERT(swr);
|
||||
|
||||
nsTArray<ServiceWorkerRegistrationData> data;
|
||||
swr->GetRegistrations(data);
|
||||
|
||||
nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID));
|
||||
if (!array) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0, len = data.Length(); i < len; ++i) {
|
||||
nsCOMPtr<nsIServiceWorkerInfo> info = ServiceWorkerDataInfo::Create(data[i]);
|
||||
if (!info) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
array->AppendElement(info, false);
|
||||
}
|
||||
|
||||
mRegistrationInfos.EnumerateRead(GetAllRegistrationsPerPrincipalEnumerator, array);
|
||||
array.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -4153,6 +4286,69 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::PropagateSoftUpdate(JS::Handle<JS::Value> aOriginAttributes,
|
||||
const nsAString& aScope,
|
||||
JSContext* aCx)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
OriginAttributes attrs;
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
PropagateSoftUpdate(attrs, aScope);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::PropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mActor) {
|
||||
nsRefPtr<nsIRunnable> runnable =
|
||||
new PropagateSoftUpdateRunnable(aOriginAttributes, aScope);
|
||||
AppendPendingOperation(runnable);
|
||||
return;
|
||||
}
|
||||
|
||||
mActor->SendPropagateSoftUpdate(aOriginAttributes, nsString(aScope));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::PropagateUnregister(nsIPrincipal* aPrincipal,
|
||||
nsIServiceWorkerUnregisterCallback* aCallback,
|
||||
const nsAString& aScope)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
if (!mActor) {
|
||||
nsRefPtr<nsIRunnable> runnable =
|
||||
new PropagateUnregisterRunnable(aPrincipal, aCallback, aScope);
|
||||
AppendPendingOperation(runnable);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PrincipalInfo principalInfo;
|
||||
if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(aPrincipal,
|
||||
&principalInfo)))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mActor->SendPropagateUnregister(principalInfo, nsString(aScope));
|
||||
|
||||
nsresult rv = Unregister(aPrincipal, aCallback, aScope);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
|
||||
{
|
||||
|
@ -35,10 +35,6 @@ namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
|
||||
namespace ipc {
|
||||
class BackgroundChild;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
||||
class ServiceWorkerRegistrationListener;
|
||||
@ -50,6 +46,7 @@ class ServiceWorkerClientInfo;
|
||||
class ServiceWorkerInfo;
|
||||
class ServiceWorkerJob;
|
||||
class ServiceWorkerJobQueue;
|
||||
class ServiceWorkerManagerChild;
|
||||
|
||||
// Needs to inherit from nsISupports because NS_ProxyRelease() does not support
|
||||
// non-ISupports classes.
|
||||
@ -304,6 +301,13 @@ public:
|
||||
void
|
||||
SoftUpdate(nsIPrincipal* aPrincipal, const nsACString& aScope);
|
||||
|
||||
void
|
||||
SoftUpdate(const OriginAttributes& aOriginAttributes, const nsACString& aScope);
|
||||
|
||||
void
|
||||
PropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope);
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||
GetRegistration(nsIPrincipal* aPrincipal, const nsACString& aScope) const;
|
||||
|
||||
@ -352,6 +356,9 @@ public:
|
||||
static already_AddRefed<ServiceWorkerManager>
|
||||
GetInstance();
|
||||
|
||||
void
|
||||
LoadRegistration(const ServiceWorkerRegistrationData& aRegistration);
|
||||
|
||||
void
|
||||
LoadRegistrations(const nsTArray<ServiceWorkerRegistrationData>& aRegistrations);
|
||||
|
||||
@ -525,7 +532,7 @@ private:
|
||||
void
|
||||
RemoveRegistrationInternal(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
mozilla::ipc::PBackgroundChild* mActor;
|
||||
nsRefPtr<ServiceWorkerManagerChild> mActor;
|
||||
|
||||
struct PendingOperation;
|
||||
nsTArray<PendingOperation> mPendingOperations;
|
||||
|
72
dom/workers/ServiceWorkerManagerChild.cpp
Normal file
72
dom/workers/ServiceWorkerManagerChild.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ServiceWorkerManagerChild.h"
|
||||
#include "ServiceWorkerManager.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerChild::RecvNotifyRegister(
|
||||
const ServiceWorkerRegistrationData& aData)
|
||||
{
|
||||
if (mShuttingDown) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
swm->LoadRegistration(aData);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerChild::RecvNotifySoftUpdate(
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope)
|
||||
{
|
||||
if (mShuttingDown) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
swm->SoftUpdate(aOriginAttributes, NS_ConvertUTF16toUTF8(aScope));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerChild::RecvNotifyUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope)
|
||||
{
|
||||
if (mShuttingDown) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(aPrincipalInfo);
|
||||
if (NS_WARN_IF(!principal)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult rv = swm->Unregister(principal, nullptr, aScope);
|
||||
unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
59
dom/workers/ServiceWorkerManagerChild.h
Normal file
59
dom/workers/ServiceWorkerManagerChild.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ServiceWorkerManagerChild_h
|
||||
#define mozilla_dom_ServiceWorkerManagerChild_h
|
||||
|
||||
#include "mozilla/dom/PServiceWorkerManagerChild.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
|
||||
namespace ipc {
|
||||
class BackgroundChildImpl;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorkerManagerChild final : public PServiceWorkerManagerChild
|
||||
{
|
||||
friend class mozilla::ipc::BackgroundChildImpl;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerManagerChild)
|
||||
|
||||
void ManagerShuttingDown()
|
||||
{
|
||||
mShuttingDown = true;
|
||||
}
|
||||
|
||||
virtual bool RecvNotifyRegister(const ServiceWorkerRegistrationData& aData)
|
||||
override;
|
||||
|
||||
virtual bool RecvNotifySoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool RecvNotifyUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope) override;
|
||||
|
||||
private:
|
||||
ServiceWorkerManagerChild()
|
||||
: mShuttingDown(false)
|
||||
{}
|
||||
|
||||
~ServiceWorkerManagerChild() {}
|
||||
|
||||
bool mShuttingDown;
|
||||
};
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_ServiceWorkerManagerChild_h
|
289
dom/workers/ServiceWorkerManagerParent.cpp
Normal file
289
dom/workers/ServiceWorkerManagerParent.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ServiceWorkerManagerParent.h"
|
||||
#include "ServiceWorkerManagerService.h"
|
||||
#include "mozilla/AppProcessChecker.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
|
||||
namespace {
|
||||
|
||||
uint64_t sServiceWorkerManagerParentID = 0;
|
||||
|
||||
void
|
||||
AssertIsInMainProcess()
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
}
|
||||
|
||||
class RegisterServiceWorkerCallback final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
RegisterServiceWorkerCallback(const ServiceWorkerRegistrationData& aData,
|
||||
uint64_t aParentID)
|
||||
: mData(aData)
|
||||
, mParentID(aParentID)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsRefPtr<dom::ServiceWorkerRegistrar> service =
|
||||
dom::ServiceWorkerRegistrar::Get();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
service->RegisterServiceWorker(mData);
|
||||
|
||||
nsRefPtr<ServiceWorkerManagerService> managerService =
|
||||
ServiceWorkerManagerService::Get();
|
||||
if (managerService) {
|
||||
managerService->PropagateRegistration(mParentID, mData);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
ServiceWorkerRegistrationData mData;
|
||||
const uint64_t mParentID;
|
||||
};
|
||||
|
||||
class UnregisterServiceWorkerCallback final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
UnregisterServiceWorkerCallback(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope)
|
||||
: mPrincipalInfo(aPrincipalInfo)
|
||||
, mScope(aScope)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsRefPtr<dom::ServiceWorkerRegistrar> service =
|
||||
dom::ServiceWorkerRegistrar::Get();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
service->UnregisterServiceWorker(mPrincipalInfo,
|
||||
NS_ConvertUTF16toUTF8(mScope));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
const PrincipalInfo mPrincipalInfo;
|
||||
nsString mScope;
|
||||
};
|
||||
|
||||
class CheckPrincipalWithCallbackRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CheckPrincipalWithCallbackRunnable(already_AddRefed<ContentParent> aParent,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
nsRunnable* aCallback)
|
||||
: mContentParent(aParent)
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
, mCallback(aCallback)
|
||||
, mBackgroundThread(NS_GetCurrentThread())
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
MOZ_ASSERT(mContentParent);
|
||||
MOZ_ASSERT(mCallback);
|
||||
MOZ_ASSERT(mBackgroundThread);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(mPrincipalInfo);
|
||||
AssertAppPrincipal(mContentParent, principal);
|
||||
mContentParent = nullptr;
|
||||
|
||||
mBackgroundThread->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AssertIsOnBackgroundThread();
|
||||
mCallback->Run();
|
||||
mCallback = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<ContentParent> mContentParent;
|
||||
PrincipalInfo mPrincipalInfo;
|
||||
nsRefPtr<nsRunnable> mCallback;
|
||||
nsCOMPtr<nsIThread> mBackgroundThread;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
ServiceWorkerManagerParent::ServiceWorkerManagerParent()
|
||||
: mService(ServiceWorkerManagerService::GetOrCreate())
|
||||
, mID(++sServiceWorkerManagerParentID)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
mService->RegisterActor(this);
|
||||
}
|
||||
|
||||
ServiceWorkerManagerParent::~ServiceWorkerManagerParent()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerParent::RecvRegister(
|
||||
const ServiceWorkerRegistrationData& aData)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// Basic validation.
|
||||
if (aData.scope().IsEmpty() ||
|
||||
aData.scriptSpec().IsEmpty() ||
|
||||
aData.principal().type() == PrincipalInfo::TNullPrincipalInfo ||
|
||||
aData.principal().type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<RegisterServiceWorkerCallback> callback =
|
||||
new RegisterServiceWorkerCallback(aData, mID);
|
||||
|
||||
nsRefPtr<ContentParent> parent =
|
||||
BackgroundParent::GetContentParent(Manager());
|
||||
|
||||
// If the ContentParent is null we are dealing with a same-process actor.
|
||||
if (!parent) {
|
||||
callback->Run();
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<CheckPrincipalWithCallbackRunnable> runnable =
|
||||
new CheckPrincipalWithCallbackRunnable(parent.forget(), aData.principal(),
|
||||
callback);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerParent::RecvUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// Basic validation.
|
||||
if (aScope.IsEmpty() ||
|
||||
aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo ||
|
||||
aPrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<UnregisterServiceWorkerCallback> callback =
|
||||
new UnregisterServiceWorkerCallback(aPrincipalInfo, aScope);
|
||||
|
||||
nsRefPtr<ContentParent> parent =
|
||||
BackgroundParent::GetContentParent(Manager());
|
||||
|
||||
// If the ContentParent is null we are dealing with a same-process actor.
|
||||
if (!parent) {
|
||||
callback->Run();
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<CheckPrincipalWithCallbackRunnable> runnable =
|
||||
new CheckPrincipalWithCallbackRunnable(parent.forget(), aPrincipalInfo,
|
||||
callback);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerParent::RecvPropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (NS_WARN_IF(!mService)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mService->PropagateSoftUpdate(mID, aOriginAttributes, aScope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerParent::RecvPropagateUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (NS_WARN_IF(!mService)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mService->PropagateUnregister(mID, aPrincipalInfo, aScope);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerManagerParent::RecvShutdown()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (NS_WARN_IF(!mService)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mService->UnregisterActor(this);
|
||||
mService = nullptr;
|
||||
|
||||
unused << Send__delete__(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManagerParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (mService) {
|
||||
// This object is about to be released and with it, also mService will be
|
||||
// released too.
|
||||
mService->UnregisterActor(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
66
dom/workers/ServiceWorkerManagerParent.h
Normal file
66
dom/workers/ServiceWorkerManagerParent.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ServiceWorkerManagerParent_h
|
||||
#define mozilla_dom_ServiceWorkerManagerParent_h
|
||||
|
||||
#include "mozilla/dom/PServiceWorkerManagerParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
|
||||
namespace ipc {
|
||||
class BackgroundParentImpl;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorkerManagerService;
|
||||
|
||||
class ServiceWorkerManagerParent final : public PServiceWorkerManagerParent
|
||||
{
|
||||
friend class mozilla::ipc::BackgroundParentImpl;
|
||||
|
||||
public:
|
||||
uint64_t ID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
private:
|
||||
ServiceWorkerManagerParent();
|
||||
~ServiceWorkerManagerParent();
|
||||
|
||||
virtual bool RecvRegister(
|
||||
const ServiceWorkerRegistrationData& aData) override;
|
||||
|
||||
virtual bool RecvUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool RecvPropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool RecvPropagateUnregister(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool RecvShutdown() override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
nsRefPtr<ServiceWorkerManagerService> mService;
|
||||
|
||||
// We use this ID in the Service in order to avoid the sending of messages to
|
||||
// ourself.
|
||||
uint64_t mID;
|
||||
};
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_ServiceWorkerManagerParent_h
|
290
dom/workers/ServiceWorkerManagerService.cpp
Normal file
290
dom/workers/ServiceWorkerManagerService.cpp
Normal file
@ -0,0 +1,290 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ServiceWorkerManagerService.h"
|
||||
#include "ServiceWorkerManagerParent.h"
|
||||
#include "ServiceWorkerRegistrar.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
namespace workers {
|
||||
|
||||
namespace {
|
||||
|
||||
ServiceWorkerManagerService* sInstance = nullptr;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
ServiceWorkerManagerService::ServiceWorkerManagerService()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// sInstance is a raw ServiceWorkerManagerService*.
|
||||
MOZ_ASSERT(!sInstance);
|
||||
sInstance = this;
|
||||
}
|
||||
|
||||
ServiceWorkerManagerService::~ServiceWorkerManagerService()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(sInstance == this);
|
||||
MOZ_ASSERT(mAgents.Count() == 0);
|
||||
|
||||
sInstance = nullptr;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<ServiceWorkerManagerService>
|
||||
ServiceWorkerManagerService::Get()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsRefPtr<ServiceWorkerManagerService> instance = sInstance;
|
||||
return instance.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<ServiceWorkerManagerService>
|
||||
ServiceWorkerManagerService::GetOrCreate()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsRefPtr<ServiceWorkerManagerService> instance = sInstance;
|
||||
if (!instance) {
|
||||
instance = new ServiceWorkerManagerService();
|
||||
}
|
||||
return instance.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManagerService::RegisterActor(ServiceWorkerManagerParent* aParent)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(!mAgents.Contains(aParent));
|
||||
|
||||
mAgents.PutEntry(aParent);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManagerService::UnregisterActor(ServiceWorkerManagerParent* aParent)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(mAgents.Contains(aParent));
|
||||
|
||||
mAgents.RemoveEntry(aParent);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct MOZ_STACK_CLASS RegistrationData final
|
||||
{
|
||||
RegistrationData(ServiceWorkerRegistrationData& aData,
|
||||
uint64_t aParentID)
|
||||
: mData(aData)
|
||||
, mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(RegistrationData);
|
||||
}
|
||||
|
||||
~RegistrationData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RegistrationData);
|
||||
}
|
||||
|
||||
const ServiceWorkerRegistrationData& mData;
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
RegistrationEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<RegistrationData*>(aPtr);
|
||||
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused << parent->SendNotifyRegister(data->mData);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct MOZ_STACK_CLASS SoftUpdateData final
|
||||
{
|
||||
SoftUpdateData(const OriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope,
|
||||
uint64_t aParentID)
|
||||
: mOriginAttributes(aOriginAttributes)
|
||||
, mScope(aScope)
|
||||
, mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(SoftUpdateData);
|
||||
}
|
||||
|
||||
~SoftUpdateData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(SoftUpdateData);
|
||||
}
|
||||
|
||||
const OriginAttributes& mOriginAttributes;
|
||||
const nsString mScope;
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
SoftUpdateEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<SoftUpdateData*>(aPtr);
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused <<parent->SendNotifySoftUpdate(data->mOriginAttributes,
|
||||
data->mScope);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct MOZ_STACK_CLASS UnregisterData final
|
||||
{
|
||||
UnregisterData(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsAString& aScope,
|
||||
uint64_t aParentID)
|
||||
: mPrincipalInfo(aPrincipalInfo)
|
||||
, mScope(aScope)
|
||||
, mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(UnregisterData);
|
||||
}
|
||||
|
||||
~UnregisterData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(UnregisterData);
|
||||
}
|
||||
|
||||
const PrincipalInfo mPrincipalInfo;
|
||||
const nsString mScope;
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
UnregisterEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<UnregisterData*>(aPtr);
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused << parent->SendNotifyUnregister(data->mPrincipalInfo, data->mScope);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
} // anonymous namespce
|
||||
|
||||
void
|
||||
ServiceWorkerManagerService::PropagateRegistration(
|
||||
uint64_t aParentID,
|
||||
ServiceWorkerRegistrationData& aData)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RegistrationData data(aData, aParentID);
|
||||
mAgents.EnumerateEntries(RegistrationEnumerator, &data);
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManagerService::PropagateSoftUpdate(
|
||||
uint64_t aParentID,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
SoftUpdateData data(aOriginAttributes, aScope, aParentID);
|
||||
mAgents.EnumerateEntries(SoftUpdateEnumerator, &data);
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManagerService::PropagateUnregister(
|
||||
uint64_t aParentID,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const nsAString& aScope)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsRefPtr<dom::ServiceWorkerRegistrar> service =
|
||||
dom::ServiceWorkerRegistrar::Get();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
// It's possible that we don't have any ServiceWorkerManager managing this
|
||||
// scope but we still need to unregister it from the ServiceWorkerRegistrar.
|
||||
service->UnregisterServiceWorker(aPrincipalInfo,
|
||||
NS_ConvertUTF16toUTF8(aScope));
|
||||
|
||||
UnregisterData data(aPrincipalInfo, aScope, aParentID);
|
||||
mAgents.EnumerateEntries(UnregisterEnumerator, &data);
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
63
dom/workers/ServiceWorkerManagerService.h
Normal file
63
dom/workers/ServiceWorkerManagerService.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ServiceWorkerManagerService_h
|
||||
#define mozilla_dom_ServiceWorkerManagerService_h
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsTHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes;
|
||||
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
||||
class ServiceWorkerRegistrationData;
|
||||
|
||||
namespace workers {
|
||||
|
||||
class ServiceWorkerManagerParent;
|
||||
|
||||
class ServiceWorkerManagerService final
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerManagerService)
|
||||
|
||||
static already_AddRefed<ServiceWorkerManagerService> Get();
|
||||
static already_AddRefed<ServiceWorkerManagerService> GetOrCreate();
|
||||
|
||||
void RegisterActor(ServiceWorkerManagerParent* aParent);
|
||||
void UnregisterActor(ServiceWorkerManagerParent* aParent);
|
||||
|
||||
void PropagateRegistration(uint64_t aParentID,
|
||||
ServiceWorkerRegistrationData& aData);
|
||||
|
||||
void PropagateSoftUpdate(uint64_t aParentID,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope);
|
||||
|
||||
void PropagateUnregister(uint64_t aParentID,
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
|
||||
const nsAString& aScope);
|
||||
|
||||
private:
|
||||
ServiceWorkerManagerService();
|
||||
~ServiceWorkerManagerService();
|
||||
|
||||
nsTHashtable<nsPtrHashKey<ServiceWorkerManagerParent>> mAgents;
|
||||
};
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_ServiceWorkerManagerService_h
|
@ -69,6 +69,9 @@ UNIFIED_SOURCES += [
|
||||
'ServiceWorkerContainer.cpp',
|
||||
'ServiceWorkerEvents.cpp',
|
||||
'ServiceWorkerManager.cpp',
|
||||
'ServiceWorkerManagerChild.cpp',
|
||||
'ServiceWorkerManagerParent.cpp',
|
||||
'ServiceWorkerManagerService.cpp',
|
||||
'ServiceWorkerPeriodicUpdater.cpp',
|
||||
'ServiceWorkerRegistrar.cpp',
|
||||
'ServiceWorkerRegistration.cpp',
|
||||
@ -86,6 +89,7 @@ UNIFIED_SOURCES += [
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PServiceWorkerManager.ipdl',
|
||||
'ServiceWorkerRegistrarTypes.ipdlh',
|
||||
]
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "ActorsChild.h" // IndexedDB
|
||||
#include "BroadcastChannelChild.h"
|
||||
#include "ServiceWorkerManagerChild.h"
|
||||
#include "FileDescriptorSetChild.h"
|
||||
#include "mozilla/media/MediaChild.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
@ -260,6 +261,28 @@ BackgroundChildImpl::DeallocPBroadcastChannelChild(
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ServiceWorkerManager
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
dom::PServiceWorkerManagerChild*
|
||||
BackgroundChildImpl::AllocPServiceWorkerManagerChild()
|
||||
{
|
||||
nsRefPtr<dom::workers::ServiceWorkerManagerChild> agent =
|
||||
new dom::workers::ServiceWorkerManagerChild();
|
||||
return agent.forget().take();
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundChildImpl::DeallocPServiceWorkerManagerChild(
|
||||
PServiceWorkerManagerChild* aActor)
|
||||
{
|
||||
nsRefPtr<dom::workers::ServiceWorkerManagerChild> child =
|
||||
dont_AddRef(static_cast<dom::workers::ServiceWorkerManagerChild*>(aActor));
|
||||
MOZ_ASSERT(child);
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Cache API
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -98,6 +98,12 @@ protected:
|
||||
virtual bool
|
||||
DeallocPBroadcastChannelChild(PBroadcastChannelChild* aActor) override;
|
||||
|
||||
virtual PServiceWorkerManagerChild*
|
||||
AllocPServiceWorkerManagerChild() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPServiceWorkerManagerChild(PServiceWorkerManagerChild* aActor) override;
|
||||
|
||||
virtual dom::cache::PCacheStorageChild*
|
||||
AllocPCacheStorageChild(const dom::cache::Namespace& aNamespace,
|
||||
const PrincipalInfo& aPrincipalInfo) override;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "ServiceWorkerManagerParent.h"
|
||||
|
||||
#ifdef DISABLE_ASSERTS_FOR_FUZZING
|
||||
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
|
||||
@ -82,6 +83,7 @@ namespace ipc {
|
||||
using mozilla::dom::ContentParent;
|
||||
using mozilla::dom::BroadcastChannelParent;
|
||||
using mozilla::dom::ServiceWorkerRegistrationData;
|
||||
using mozilla::dom::workers::ServiceWorkerManagerParent;
|
||||
|
||||
BackgroundParentImpl::BackgroundParentImpl()
|
||||
{
|
||||
@ -468,6 +470,27 @@ BackgroundParentImpl::DeallocPBroadcastChannelParent(
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::dom::PServiceWorkerManagerParent*
|
||||
BackgroundParentImpl::AllocPServiceWorkerManagerParent()
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
return new ServiceWorkerManagerParent();
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundParentImpl::DeallocPServiceWorkerManagerParent(
|
||||
PServiceWorkerManagerParent* aActor)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
delete static_cast<ServiceWorkerManagerParent*>(aActor);
|
||||
return true;
|
||||
}
|
||||
|
||||
media::PMediaParent*
|
||||
BackgroundParentImpl::AllocPMediaParent()
|
||||
{
|
||||
@ -480,187 +503,6 @@ BackgroundParentImpl::DeallocPMediaParent(media::PMediaParent *aActor)
|
||||
return media::DeallocPMediaParent(aActor);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class RegisterServiceWorkerCallback final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit RegisterServiceWorkerCallback(
|
||||
const ServiceWorkerRegistrationData& aData)
|
||||
: mData(aData)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsRefPtr<dom::ServiceWorkerRegistrar> service =
|
||||
dom::ServiceWorkerRegistrar::Get();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
service->RegisterServiceWorker(mData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
ServiceWorkerRegistrationData mData;
|
||||
};
|
||||
|
||||
class UnregisterServiceWorkerCallback final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
UnregisterServiceWorkerCallback(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope)
|
||||
: mPrincipalInfo(aPrincipalInfo)
|
||||
, mScope(aScope)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsRefPtr<dom::ServiceWorkerRegistrar> service =
|
||||
dom::ServiceWorkerRegistrar::Get();
|
||||
MOZ_ASSERT(service);
|
||||
|
||||
service->UnregisterServiceWorker(mPrincipalInfo,
|
||||
NS_ConvertUTF16toUTF8(mScope));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
const PrincipalInfo mPrincipalInfo;
|
||||
nsString mScope;
|
||||
};
|
||||
|
||||
class CheckPrincipalWithCallbackRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CheckPrincipalWithCallbackRunnable(already_AddRefed<ContentParent> aParent,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
nsRunnable* aCallback)
|
||||
: mContentParent(aParent)
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
, mCallback(aCallback)
|
||||
, mBackgroundThread(NS_GetCurrentThread())
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
MOZ_ASSERT(mContentParent);
|
||||
MOZ_ASSERT(mCallback);
|
||||
MOZ_ASSERT(mBackgroundThread);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(mPrincipalInfo);
|
||||
AssertAppPrincipal(mContentParent, principal);
|
||||
mContentParent = nullptr;
|
||||
|
||||
mBackgroundThread->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AssertIsOnBackgroundThread();
|
||||
if (mCallback) {
|
||||
mCallback->Run();
|
||||
mCallback = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<ContentParent> mContentParent;
|
||||
PrincipalInfo mPrincipalInfo;
|
||||
nsRefPtr<nsRunnable> mCallback;
|
||||
nsCOMPtr<nsIThread> mBackgroundThread;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
bool
|
||||
BackgroundParentImpl::RecvRegisterServiceWorker(
|
||||
const ServiceWorkerRegistrationData& aData)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// Basic validation.
|
||||
if (aData.scope().IsEmpty() ||
|
||||
aData.scriptSpec().IsEmpty() ||
|
||||
aData.principal().type() == PrincipalInfo::TNullPrincipalInfo ||
|
||||
aData.principal().type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<RegisterServiceWorkerCallback> callback =
|
||||
new RegisterServiceWorkerCallback(aData);
|
||||
|
||||
nsRefPtr<ContentParent> parent = BackgroundParent::GetContentParent(this);
|
||||
|
||||
// If the ContentParent is null we are dealing with a same-process actor.
|
||||
if (!parent) {
|
||||
callback->Run();
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<CheckPrincipalWithCallbackRunnable> runnable =
|
||||
new CheckPrincipalWithCallbackRunnable(parent.forget(), aData.principal(),
|
||||
callback);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundParentImpl::RecvUnregisterServiceWorker(
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope)
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// Basic validation.
|
||||
if (aScope.IsEmpty() ||
|
||||
aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo ||
|
||||
aPrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<UnregisterServiceWorkerCallback> callback =
|
||||
new UnregisterServiceWorkerCallback(aPrincipalInfo, aScope);
|
||||
|
||||
nsRefPtr<ContentParent> parent = BackgroundParent::GetContentParent(this);
|
||||
|
||||
// If the ContentParent is null we are dealing with a same-process actor.
|
||||
if (!parent) {
|
||||
callback->Run();
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<CheckPrincipalWithCallbackRunnable> runnable =
|
||||
new CheckPrincipalWithCallbackRunnable(parent.forget(), aPrincipalInfo,
|
||||
callback);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundParentImpl::RecvShutdownServiceWorkerRegistrar()
|
||||
{
|
||||
|
@ -86,20 +86,18 @@ protected:
|
||||
virtual bool
|
||||
DeallocPBroadcastChannelParent(PBroadcastChannelParent* aActor) override;
|
||||
|
||||
virtual PServiceWorkerManagerParent*
|
||||
AllocPServiceWorkerManagerParent() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPServiceWorkerManagerParent(PServiceWorkerManagerParent* aActor) override;
|
||||
|
||||
virtual PMediaParent*
|
||||
AllocPMediaParent() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPMediaParent(PMediaParent* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvRegisterServiceWorker(const ServiceWorkerRegistrationData& aData)
|
||||
override;
|
||||
|
||||
virtual bool
|
||||
RecvUnregisterServiceWorker(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsString& aScope) override;
|
||||
|
||||
virtual bool
|
||||
RecvShutdownServiceWorkerRegistrar() override;
|
||||
|
||||
|
@ -5,12 +5,38 @@
|
||||
#ifndef mozilla_ipc_backgroundutils_h__
|
||||
#define mozilla_ipc_backgroundutils_h__
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::OriginAttributes>
|
||||
{
|
||||
typedef mozilla::OriginAttributes paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
nsAutoCString suffix;
|
||||
aParam.CreateSuffix(suffix);
|
||||
WriteParam(aMsg, suffix);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
nsAutoCString suffix;
|
||||
return ReadParam(aMsg, aIter, &suffix) &&
|
||||
aResult->PopulateFromSuffix(suffix);
|
||||
}
|
||||
};
|
||||
|
||||
} // IPC namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
|
@ -11,13 +11,13 @@ include protocol PCacheStorage;
|
||||
include protocol PCacheStreamControl;
|
||||
include protocol PFileDescriptorSet;
|
||||
include protocol PMedia;
|
||||
include protocol PServiceWorkerManager;
|
||||
include protocol PUDPSocket;
|
||||
include protocol PVsync;
|
||||
|
||||
include DOMTypes;
|
||||
include PBackgroundSharedTypes;
|
||||
include PBackgroundIDBSharedTypes;
|
||||
include ServiceWorkerRegistrarTypes;
|
||||
|
||||
using mozilla::dom::cache::Namespace from "mozilla/dom/cache/Types.h";
|
||||
include "mozilla/dom/cache/IPCUtils.h";
|
||||
@ -36,6 +36,7 @@ sync protocol PBackground
|
||||
manages PCacheStreamControl;
|
||||
manages PFileDescriptorSet;
|
||||
manages PMedia;
|
||||
manages PServiceWorkerManager;
|
||||
manages PUDPSocket;
|
||||
manages PVsync;
|
||||
|
||||
@ -52,9 +53,8 @@ parent:
|
||||
PBroadcastChannel(PrincipalInfo pInfo, nsString origin, nsString channel,
|
||||
bool privateBrowsing);
|
||||
|
||||
RegisterServiceWorker(ServiceWorkerRegistrationData data);
|
||||
UnregisterServiceWorker(PrincipalInfo principalInfo,
|
||||
nsString scope);
|
||||
PServiceWorkerManager();
|
||||
|
||||
ShutdownServiceWorkerRegistrar();
|
||||
|
||||
PCacheStorage(Namespace aNamespace, PrincipalInfo aPrincipalInfo);
|
||||
|
@ -133,6 +133,7 @@ LOCAL_INCLUDES += [
|
||||
'/caps',
|
||||
'/dom/broadcastchannel',
|
||||
'/dom/indexedDB',
|
||||
'/dom/workers',
|
||||
'/xpcom/build',
|
||||
]
|
||||
|
||||
|
@ -132,7 +132,7 @@ function display(info) {
|
||||
let updateButton = document.createElement("button");
|
||||
updateButton.appendChild(document.createTextNode(bundle.GetStringFromName('update')));
|
||||
updateButton.onclick = function() {
|
||||
gSWM.softUpdate(info.principal.originAttributes, info.scope);
|
||||
gSWM.propagateSoftUpdate(info.principal.originAttributes, info.scope);
|
||||
};
|
||||
div.appendChild(updateButton);
|
||||
|
||||
@ -164,7 +164,7 @@ function display(info) {
|
||||
};
|
||||
|
||||
loadingMessage.classList.remove('inactive');
|
||||
gSWM.unregister(info.principal, cb, info.scope);
|
||||
gSWM.propagateUnregister(info.principal, cb, info.scope);
|
||||
};
|
||||
|
||||
let sep = document.createElement('hr');
|
||||
|
Loading…
Reference in New Issue
Block a user