Bug 1257401 - Remove the worker descriptor for PushManager. r=khuey

MozReview-Commit-ID: 4nZElH1K3W5

--HG--
extra : rebase_source : d325e2fc44124acc0bd04b133605bf04a99ab906
This commit is contained in:
Kit Cambridge 2016-04-01 15:25:49 -07:00
parent 9bf9d2c2c9
commit 2bfd46b860
9 changed files with 236 additions and 306 deletions

View File

@ -955,16 +955,6 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::workers::PushMessageData',
},
'PushManager': [{
'workers': False,
'headerFile': 'mozilla/dom/PushManager.h',
'nativeType': 'mozilla::dom::PushManager',
}, {
'workers': True,
'headerFile': 'mozilla/dom/PushManager.h',
'nativeType': 'mozilla::dom::WorkerPushManager',
}],
'Range': {
'nativeType': 'nsRange',
'binaryNames': {
@ -1008,6 +998,7 @@ DOMInterfaces = {
'ServiceWorkerRegistration': [{
'nativeType': 'mozilla::dom::ServiceWorkerRegistrationMainThread',
'headerFile': 'mozilla/dom/ServiceWorkerRegistration.h',
'implicitJSContext': [ 'pushManager' ],
}, {
'workers': True,
'nativeType': 'mozilla::dom::ServiceWorkerRegistrationWorkerThread',

View File

@ -56,8 +56,7 @@ Push.prototype = {
this._principal = aWindow.document.nodePrincipal;
},
setScope: function(scope){
console.debug("setScope()", scope);
__init: function(scope) {
this._scope = scope;
},

View File

@ -6,13 +6,10 @@
#include "mozilla/dom/PushManager.h"
#include "mozilla/Base64.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/unused.h"
#include "mozilla/dom/PushManagerBinding.h"
#include "mozilla/dom/PushSubscription.h"
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseWorkerProxy.h"
@ -23,8 +20,7 @@
#include "nsIPushService.h"
#include "nsComponentManagerUtils.h"
#include "nsFrameMessageManager.h"
#include "nsContentCID.h"
#include "nsContentUtils.h"
#include "WorkerRunnable.h"
#include "WorkerPrivate.h"
@ -39,7 +35,7 @@ namespace {
nsresult
GetPermissionState(nsIPrincipal* aPrincipal,
PushPermissionState& aState)
PushPermissionState& aState)
{
nsCOMPtr<nsIPermissionManager> permManager =
mozilla::services::GetPermissionManager();
@ -63,95 +59,27 @@ GetPermissionState(nsIPrincipal* aPrincipal,
} else {
aState = PushPermissionState::Prompt;
}
return NS_OK;
}
} // anonymous namespace
PushManager::PushManager(nsIGlobalObject* aGlobal, const nsAString& aScope)
: mGlobal(aGlobal), mScope(aScope)
{
AssertIsOnMainThread();
}
PushManager::~PushManager()
{}
JSObject*
PushManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
// XXXnsm I don't know if this is the right way to do it, but I want to assert
// that an implementation has been set before this object gets exposed to JS.
MOZ_ASSERT(mImpl);
return PushManagerBinding::Wrap(aCx, this, aGivenProto);
}
void
PushManager::SetPushManagerImpl(PushManagerImpl& foo, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mImpl);
mImpl = &foo;
}
already_AddRefed<Promise>
PushManager::Subscribe(ErrorResult& aRv)
{
MOZ_ASSERT(mImpl);
return mImpl->Subscribe(aRv);
}
already_AddRefed<Promise>
PushManager::GetSubscription(ErrorResult& aRv)
{
MOZ_ASSERT(mImpl);
return mImpl->GetSubscription(aRv);
}
already_AddRefed<Promise>
PushManager::PermissionState(ErrorResult& aRv)
{
MOZ_ASSERT(mImpl);
return mImpl->PermissionState(aRv);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PushManager, mGlobal, mImpl)
NS_IMPL_CYCLE_COLLECTING_ADDREF(PushManager)
NS_IMPL_CYCLE_COLLECTING_RELEASE(PushManager)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PushManager)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
// WorkerPushManager
WorkerPushManager::WorkerPushManager(const nsAString& aScope)
: mScope(aScope)
{
}
JSObject*
WorkerPushManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return PushManagerBinding_workers::Wrap(aCx, this, aGivenProto);
}
class GetSubscriptionResultRunnable final : public WorkerRunnable
{
public:
GetSubscriptionResultRunnable(PromiseWorkerProxy* aProxy,
GetSubscriptionResultRunnable(WorkerPrivate* aWorkerPrivate,
already_AddRefed<PromiseWorkerProxy>&& aProxy,
nsresult aStatus,
const nsAString& aEndpoint,
const nsAString& aScope,
const nsTArray<uint8_t>& aRawP256dhKey,
const nsTArray<uint8_t>& aAuthSecret)
: WorkerRunnable(aProxy->GetWorkerPrivate(), WorkerThreadModifyBusyCount)
, mProxy(aProxy)
nsTArray<uint8_t>&& aRawP256dhKey,
nsTArray<uint8_t>&& aAuthSecret)
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount)
, mProxy(Move(aProxy))
, mStatus(aStatus)
, mEndpoint(aEndpoint)
, mScope(aScope)
, mRawP256dhKey(aRawP256dhKey)
, mAuthSecret(aAuthSecret)
, mRawP256dhKey(Move(aRawP256dhKey))
, mAuthSecret(Move(aAuthSecret))
{ }
bool
@ -163,8 +91,8 @@ public:
promise->MaybeResolve(JS::NullHandleValue);
} else {
RefPtr<PushSubscription> sub =
new PushSubscription(nullptr, mEndpoint, mScope, mRawP256dhKey,
mAuthSecret);
new PushSubscription(nullptr, mEndpoint, mScope,
Move(mRawP256dhKey), Move(mAuthSecret));
promise->MaybeResolve(sub);
}
} else if (NS_ERROR_GET_MODULE(mStatus) == NS_ERROR_MODULE_DOM_PUSH ) {
@ -174,6 +102,7 @@ public:
}
mProxy->CleanUp();
return true;
}
private:
@ -206,10 +135,8 @@ public:
AssertIsOnMainThread();
MOZ_ASSERT(mProxy, "OnPushSubscription() called twice?");
RefPtr<PromiseWorkerProxy> proxy = mProxy.forget();
MutexAutoLock lock(proxy->Lock());
if (proxy->CleanedUp()) {
MutexAutoLock lock(mProxy->Lock());
if (mProxy->CleanedUp()) {
return NS_OK;
}
@ -220,14 +147,17 @@ public:
authSecret);
}
WorkerPrivate* worker = mProxy->GetWorkerPrivate();
RefPtr<GetSubscriptionResultRunnable> r =
new GetSubscriptionResultRunnable(proxy,
new GetSubscriptionResultRunnable(worker,
mProxy.forget(),
aStatus,
endpoint,
mScope,
rawP256dhKey,
authSecret);
r->Dispatch();
Move(rawP256dhKey),
Move(authSecret));
MOZ_ALWAYS_TRUE(r->Dispatch());
return NS_OK;
}
@ -249,6 +179,7 @@ private:
{
NS_Free(aKey);
NS_Free(aAuthSecret);
return aStatus;
}
@ -306,7 +237,7 @@ class GetSubscriptionRunnable final : public nsRunnable
public:
GetSubscriptionRunnable(PromiseWorkerProxy* aProxy,
const nsAString& aScope,
WorkerPushManager::SubscriptionAction aAction)
PushManager::SubscriptionAction aAction)
: mProxy(aProxy)
, mScope(aScope), mAction(aAction)
{}
@ -317,6 +248,7 @@ public:
AssertIsOnMainThread();
nsCOMPtr<nsIPrincipal> principal;
{
// Bug 1228723: If permission is revoked or an error occurs, the
// subscription callback will be called synchronously. This causes
@ -328,6 +260,7 @@ public:
}
principal = mProxy->GetWorkerPrivate()->GetPrincipal();
}
MOZ_ASSERT(principal);
RefPtr<GetSubscriptionCallback> callback = new GetSubscriptionCallback(mProxy, mScope);
@ -340,7 +273,7 @@ public:
}
if (state != PushPermissionState::Granted) {
if (mAction == WorkerPushManager::GetSubscriptionAction) {
if (mAction == PushManager::GetSubscriptionAction) {
callback->OnPushSubscriptionError(NS_OK);
return NS_OK;
}
@ -350,15 +283,15 @@ public:
nsCOMPtr<nsIPushService> service =
do_GetService("@mozilla.org/push/Service;1");
if (!service) {
if (NS_WARN_IF(!service)) {
callback->OnPushSubscriptionError(NS_ERROR_FAILURE);
return NS_OK;
}
if (mAction == WorkerPushManager::SubscribeAction) {
if (mAction == PushManager::SubscribeAction) {
rv = service->Subscribe(mScope, principal, callback);
} else {
MOZ_ASSERT(mAction == WorkerPushManager::GetSubscriptionAction);
MOZ_ASSERT(mAction == PushManager::GetSubscriptionAction);
rv = service->GetSubscription(mScope, principal, callback);
}
@ -376,47 +309,9 @@ private:
RefPtr<PromiseWorkerProxy> mProxy;
nsString mScope;
WorkerPushManager::SubscriptionAction mAction;
PushManager::SubscriptionAction mAction;
};
already_AddRefed<Promise>
WorkerPushManager::PerformSubscriptionAction(SubscriptionAction aAction, ErrorResult& aRv)
{
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
nsCOMPtr<nsIGlobalObject> global = worker->GlobalScope();
RefPtr<Promise> p = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
RefPtr<PromiseWorkerProxy> proxy = PromiseWorkerProxy::Create(worker, p);
if (!proxy) {
p->MaybeReject(NS_ERROR_DOM_PUSH_ABORT_ERR);
return p.forget();
}
RefPtr<GetSubscriptionRunnable> r =
new GetSubscriptionRunnable(proxy, mScope, aAction);
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return p.forget();
}
already_AddRefed<Promise>
WorkerPushManager::Subscribe(ErrorResult& aRv)
{
return PerformSubscriptionAction(SubscribeAction, aRv);
}
already_AddRefed<Promise>
WorkerPushManager::GetSubscription(ErrorResult& aRv)
{
return PerformSubscriptionAction(GetSubscriptionAction, aRv);
}
class PermissionResultRunnable final : public WorkerRunnable
{
public:
@ -445,6 +340,7 @@ public:
}
mProxy->CleanUp();
return true;
}
@ -481,7 +377,8 @@ public:
RefPtr<PermissionResultRunnable> r =
new PermissionResultRunnable(mProxy, rv, state);
r->Dispatch();
MOZ_ALWAYS_TRUE(r->Dispatch());
return NS_OK;
}
@ -492,9 +389,99 @@ private:
RefPtr<PromiseWorkerProxy> mProxy;
};
already_AddRefed<Promise>
WorkerPushManager::PermissionState(ErrorResult& aRv)
} // anonymous namespace
PushManager::PushManager(nsIGlobalObject* aGlobal, PushManagerImpl* aImpl)
: mGlobal(aGlobal)
, mImpl(aImpl)
{
AssertIsOnMainThread();
MOZ_ASSERT(aImpl);
}
PushManager::PushManager(const nsAString& aScope)
: mScope(aScope)
{
#ifdef DEBUG
// There's only one global on a worker, so we don't need to pass a global
// object to the constructor.
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
#endif
}
PushManager::~PushManager()
{}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PushManager, mGlobal, mImpl)
NS_IMPL_CYCLE_COLLECTING_ADDREF(PushManager)
NS_IMPL_CYCLE_COLLECTING_RELEASE(PushManager)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PushManager)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
JSObject*
PushManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return PushManagerBinding::Wrap(aCx, this, aGivenProto);
}
// static
already_AddRefed<PushManager>
PushManager::Constructor(GlobalObject& aGlobal,
const nsAString& aScope,
ErrorResult& aRv)
{
if (!NS_IsMainThread()) {
RefPtr<PushManager> ret = new PushManager(aScope);
return ret.forget();
}
RefPtr<PushManagerImpl> impl = PushManagerImpl::Constructor(aGlobal,
aGlobal.Context(),
aScope, aRv);
if (aRv.Failed()) {
return nullptr;
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<PushManager> ret = new PushManager(global, impl);
return ret.forget();
}
already_AddRefed<Promise>
PushManager::Subscribe(ErrorResult& aRv)
{
if (mImpl) {
MOZ_ASSERT(NS_IsMainThread());
return mImpl->Subscribe(aRv);
}
return PerformSubscriptionActionFromWorker(SubscribeAction, aRv);
}
already_AddRefed<Promise>
PushManager::GetSubscription(ErrorResult& aRv)
{
if (mImpl) {
MOZ_ASSERT(NS_IsMainThread());
return mImpl->GetSubscription(aRv);
}
return PerformSubscriptionActionFromWorker(GetSubscriptionAction, aRv);
}
already_AddRefed<Promise>
PushManager::PermissionState(ErrorResult& aRv)
{
if (mImpl) {
MOZ_ASSERT(NS_IsMainThread());
return mImpl->PermissionState(aRv);
}
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
@ -518,15 +505,32 @@ WorkerPushManager::PermissionState(ErrorResult& aRv)
return p.forget();
}
WorkerPushManager::~WorkerPushManager()
{}
already_AddRefed<Promise>
PushManager::PerformSubscriptionActionFromWorker(
SubscriptionAction aAction, ErrorResult& aRv)
{
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
nsCOMPtr<nsIGlobalObject> global = worker->GlobalScope();
RefPtr<Promise> p = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
RefPtr<PromiseWorkerProxy> proxy = PromiseWorkerProxy::Create(worker, p);
if (!proxy) {
p->MaybeReject(NS_ERROR_DOM_PUSH_ABORT_ERR);
return p.forget();
}
RefPtr<GetSubscriptionRunnable> r =
new GetSubscriptionRunnable(proxy, mScope, aAction);
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return p.forget();
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WorkerPushManager)
NS_IMPL_CYCLE_COLLECTING_ADDREF(WorkerPushManager)
NS_IMPL_CYCLE_COLLECTING_RELEASE(WorkerPushManager)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkerPushManager)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
} // namespace dom
} // namespace mozilla

View File

@ -5,24 +5,19 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* We would like to expose PushManager and PushSubscription on window and
* workers. Parts of the Push API is implemented in JS out of necessity due to:
* 1) Using frame message managers, in which
* nsIMessageListener::receiveMessage() must be in JS.
* 2) It is easier to use certain APIs like the permission prompt and Promises
* from JS.
* PushManager and PushSubscription are exposed on the main and worker threads.
* The main thread version is implemented in Push.js. The JS implementation
* makes it easier to use certain APIs like the permission prompt and Promises.
*
* Unfortunately, JS-implemented WebIDL is not supported off the main thread. To
* aid in fixing this, the nsIPushClient is introduced which deals with part (1)
* above. Part (2) is handled by PushManagerImpl on the main thread. PushManager
* wraps this in C++ since our bindings code cannot accomodate "JS-implemented
* on the main thread, C++ on the worker" bindings. PushManager simply forwards
* the calls to the JS component.
* Unfortunately, JS-implemented WebIDL is not supported off the main thread.
* To work around this, we use a chain of runnables to query the JS-implemented
* nsIPushService component for subscription information, and return the
* results to the worker. We don't have to deal with permission prompts, since
* we just reject calls if the principal does not have permission.
*
* On the worker threads, we don't have to deal with permission prompts, instead
* we just reject calls if the principal does not have permission. On workers
* WorkerPushManager dispatches runnables to the main thread which directly call
* nsIPushClient.
* On the main thread, PushManager wraps a JS-implemented PushManagerImpl
* instance. The C++ wrapper is necessary because our bindings code cannot
* accomodate "JS-implemented on the main thread, C++ on the worker" bindings.
*
* PushSubscription is in C++ on both threads since it isn't particularly
* verbose to implement in C++ compared to JS.
@ -40,7 +35,6 @@
#include "nsCOMPtr.h"
#include "mozilla/RefPtr.h"
#include "jsapi.h"
class nsIGlobalObject;
class nsIPrincipal;
@ -55,8 +49,6 @@ class WorkerPrivate;
class Promise;
class PushManagerImpl;
class PushManager final : public nsISupports
, public nsWrapperCache
{
@ -64,7 +56,16 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PushManager)
explicit PushManager(nsIGlobalObject* aGlobal, const nsAString& aScope);
enum SubscriptionAction {
SubscribeAction,
GetSubscriptionAction,
};
// The main thread constructor.
PushManager(nsIGlobalObject* aGlobal, PushManagerImpl* aImpl);
// The worker thread constructor.
explicit PushManager(const nsAString& aScope);
nsIGlobalObject*
GetParentObject() const
@ -75,6 +76,14 @@ public:
JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<PushManager>
Constructor(GlobalObject& aGlobal, const nsAString& aScope,
ErrorResult& aRv);
already_AddRefed<Promise>
PerformSubscriptionActionFromWorker(SubscriptionAction aAction,
ErrorResult& aRv);
already_AddRefed<Promise>
Subscribe(ErrorResult& aRv);
@ -84,57 +93,15 @@ public:
already_AddRefed<Promise>
PermissionState(ErrorResult& aRv);
void
SetPushManagerImpl(PushManagerImpl& foo, ErrorResult& aRv);
protected:
~PushManager();
private:
// The following are only set and accessed on the main thread.
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<PushManagerImpl> mImpl;
nsString mScope;
};
class WorkerPushManager final : public nsISupports
, public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WorkerPushManager)
enum SubscriptionAction {
SubscribeAction,
GetSubscriptionAction,
};
explicit WorkerPushManager(const nsAString& aScope);
nsIGlobalObject*
GetParentObject() const
{
return nullptr;
}
JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
already_AddRefed<Promise>
PerformSubscriptionAction(SubscriptionAction aAction, ErrorResult& aRv);
already_AddRefed<Promise>
Subscribe(ErrorResult& aRv);
already_AddRefed<Promise>
GetSubscription(ErrorResult& aRv);
already_AddRefed<Promise>
PermissionState(ErrorResult& aRv);
protected:
~WorkerPushManager();
private:
// Only used on the worker thread.
nsString mScope;
};
} // namespace dom

View File

@ -191,17 +191,30 @@ private:
nsString mScope;
};
bool
CopyArrayBufferToArray(const ArrayBuffer& aBuffer,
nsTArray<uint8_t>& aArray)
{
aBuffer.ComputeLengthAndData();
if (!aArray.SetLength(aBuffer.Length(), fallible) ||
!aArray.ReplaceElementsAt(0, aBuffer.Length(), aBuffer.Data(),
aBuffer.Length(), fallible)) {
return false;
}
return true;
}
} // anonymous namespace
PushSubscription::PushSubscription(nsIGlobalObject* aGlobal,
const nsAString& aEndpoint,
const nsAString& aScope,
const nsTArray<uint8_t>& aRawP256dhKey,
const nsTArray<uint8_t>& aAuthSecret)
nsTArray<uint8_t>&& aRawP256dhKey,
nsTArray<uint8_t>&& aAuthSecret)
: mEndpoint(aEndpoint)
, mScope(aScope)
, mRawP256dhKey(aRawP256dhKey)
, mAuthSecret(aAuthSecret)
, mRawP256dhKey(Move(aRawP256dhKey))
, mAuthSecret(Move(aAuthSecret))
{
if (NS_IsMainThread()) {
mGlobal = aGlobal;
@ -245,27 +258,20 @@ PushSubscription::Constructor(GlobalObject& aGlobal,
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
nsTArray<uint8_t> rawKey;
if (!aP256dhKey.IsNull()) {
const ArrayBuffer& key = aP256dhKey.Value();
key.ComputeLengthAndData();
rawKey.SetLength(key.Length());
rawKey.ReplaceElementsAt(0, key.Length(), key.Data(), key.Length());
nsTArray<uint8_t> rawKey, authSecret;
if ((!aP256dhKey.IsNull() && !CopyArrayBufferToArray(aP256dhKey.Value(),
rawKey)) ||
(!aAuthSecret.IsNull() && !CopyArrayBufferToArray(aAuthSecret.Value(),
authSecret))) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
nsTArray<uint8_t> authSecret;
if (!aAuthSecret.IsNull()) {
const ArrayBuffer& sekrit = aAuthSecret.Value();
sekrit.ComputeLengthAndData();
authSecret.SetLength(sekrit.Length());
authSecret.ReplaceElementsAt(0, sekrit.Length(),
sekrit.Data(), sekrit.Length());
}
RefPtr<PushSubscription> sub = new PushSubscription(global,
aEndpoint,
aScope,
rawKey,
authSecret);
Move(rawKey),
Move(authSecret));
return sub.forget();
}

View File

@ -38,8 +38,8 @@ public:
PushSubscription(nsIGlobalObject* aGlobal,
const nsAString& aEndpoint,
const nsAString& aScope,
const nsTArray<uint8_t>& aP256dhKey,
const nsTArray<uint8_t>& aAuthSecret);
nsTArray<uint8_t>&& aP256dhKey,
nsTArray<uint8_t>&& aAuthSecret);
JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;

View File

@ -7,30 +7,23 @@
* https://w3c.github.io/push-api/
*/
// Please see comments in dom/push/PushManager.h for the split between
// PushManagerImpl and PushManager.
// The main thread JS implementation. Please see comments in
// dom/push/PushManager.h for the split between PushManagerImpl and PushManager.
[JSImplementation="@mozilla.org/push/PushManager;1",
NoInterfaceObject]
ChromeOnly, Constructor(DOMString scope)]
interface PushManagerImpl {
Promise<PushSubscription> subscribe();
Promise<PushSubscription?> getSubscription();
Promise<PushPermissionState> permissionState();
// We need a setter in the bindings so that the C++ can use it,
// but we don't want it exposed to client JS. WebPushMethodHider
// always returns false.
[Func="ServiceWorkerRegistration::WebPushMethodHider"] void setScope(DOMString scope);
Promise<PushSubscription> subscribe();
Promise<PushSubscription?> getSubscription();
Promise<PushPermissionState> permissionState();
};
[Exposed=(Window,Worker), Func="nsContentUtils::PushEnabled"]
[Exposed=(Window,Worker), Func="nsContentUtils::PushEnabled",
ChromeConstructor(DOMString scope)]
interface PushManager {
[ChromeOnly, Throws, Exposed=Window]
void setPushManagerImpl(PushManagerImpl store);
[Throws, UseCounter]
Promise<PushSubscription> subscribe();
Promise<PushSubscription> subscribe();
[Throws]
Promise<PushSubscription?> getSubscription();
Promise<PushSubscription?> getSubscription();
[Throws]
Promise<PushPermissionState> permissionState();
};

View File

@ -752,7 +752,8 @@ ServiceWorkerRegistrationMainThread::GetNotifications(const GetNotificationOptio
}
already_AddRefed<PushManager>
ServiceWorkerRegistrationMainThread::GetPushManager(ErrorResult& aRv)
ServiceWorkerRegistrationMainThread::GetPushManager(JSContext* aCx,
ErrorResult& aRv)
{
AssertIsOnMainThread();
@ -768,32 +769,17 @@ ServiceWorkerRegistrationMainThread::GetPushManager(ErrorResult& aRv)
return nullptr;
}
// TODO: bug 1148117. This will fail when swr is exposed on workers
JS::Rooted<JSObject*> jsImplObj(nsContentUtils::RootingCxForThread());
ConstructJSImplementation("@mozilla.org/push/PushManager;1",
globalObject, &jsImplObj, aRv);
GlobalObject global(aCx, globalObject->GetGlobalJSObject());
mPushManager = PushManager::Constructor(global, mScope, aRv);
if (aRv.Failed()) {
return nullptr;
}
mPushManager = new PushManager(globalObject, mScope);
RefPtr<PushManagerImpl> impl = new PushManagerImpl(jsImplObj, globalObject);
impl->SetScope(mScope, aRv);
if (aRv.Failed()) {
mPushManager = nullptr;
return nullptr;
}
mPushManager->SetPushManagerImpl(*impl, aRv);
if (aRv.Failed()) {
mPushManager = nullptr;
return nullptr;
}
}
RefPtr<PushManager> ret = mPushManager;
return ret.forget();
#endif /* ! MOZ_SIMPLEPUSH */
#endif /* ! MOZ_SIMPLEPUSH */
}
////////////////////////////////////////////////////
@ -1217,7 +1203,7 @@ ServiceWorkerRegistrationWorkerThread::GetNotifications(const GetNotificationOpt
return Notification::WorkerGet(mWorkerPrivate, aOptions, mScope, aRv);
}
already_AddRefed<WorkerPushManager>
already_AddRefed<PushManager>
ServiceWorkerRegistrationWorkerThread::GetPushManager(ErrorResult& aRv)
{
#ifdef MOZ_SIMPLEPUSH
@ -1225,13 +1211,13 @@ ServiceWorkerRegistrationWorkerThread::GetPushManager(ErrorResult& aRv)
#else
if (!mPushManager) {
mPushManager = new WorkerPushManager(mScope);
mPushManager = new PushManager(mScope);
}
RefPtr<WorkerPushManager> ret = mPushManager;
RefPtr<PushManager> ret = mPushManager;
return ret.forget();
#endif /* ! MOZ_SIMPLEPUSH */
#endif /* ! MOZ_SIMPLEPUSH */
}
} // dom namespace

View File

@ -22,7 +22,6 @@ namespace dom {
class Promise;
class PushManager;
class WorkerPushManager;
class WorkerListener;
namespace workers {
@ -36,21 +35,6 @@ ServiceWorkerRegistrationVisible(JSContext* aCx, JSObject* aObj);
bool
ServiceWorkerNotificationAPIVisible(JSContext* aCx, JSObject* aObj);
// This class exists solely so that we can satisfy some WebIDL Func= attribute
// constraints. Func= converts the function name to a header file to include, in
// this case "ServiceWorkerRegistration.h".
class ServiceWorkerRegistration final
{
public:
// Something that we can feed into the Func webidl property to ensure that
// SetScope is never exposed to the user.
static bool
WebPushMethodHider(JSContext* unusedContext, JSObject* unusedObject) {
return false;
}
};
// Used by ServiceWorkerManager to notify ServiceWorkerRegistrations of
// updatefound event and invalidating ServiceWorker instances.
class ServiceWorkerRegistrationListener
@ -139,7 +123,7 @@ public:
GetActive() override;
already_AddRefed<PushManager>
GetPushManager(ErrorResult& aRv);
GetPushManager(JSContext* aCx, ErrorResult& aRv);
// DOMEventTargethelper
void DisconnectFromOwner() override
@ -241,7 +225,7 @@ public:
bool
Notify(workers::Status aStatus) override;
already_AddRefed<WorkerPushManager>
already_AddRefed<PushManager>
GetPushManager(ErrorResult& aRv);
private:
@ -263,7 +247,7 @@ private:
RefPtr<WorkerListener> mListener;
#ifndef MOZ_SIMPLEPUSH
RefPtr<WorkerPushManager> mPushManager;
RefPtr<PushManager> mPushManager;
#endif
};