mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 04:38:02 +00:00
Bug 1257401 - Remove the worker descriptor for PushManager
. r=khuey
MozReview-Commit-ID: 4nZElH1K3W5 --HG-- extra : rebase_source : d325e2fc44124acc0bd04b133605bf04a99ab906
This commit is contained in:
parent
9bf9d2c2c9
commit
2bfd46b860
@ -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',
|
||||
|
@ -56,8 +56,7 @@ Push.prototype = {
|
||||
this._principal = aWindow.document.nodePrincipal;
|
||||
},
|
||||
|
||||
setScope: function(scope){
|
||||
console.debug("setScope()", scope);
|
||||
__init: function(scope) {
|
||||
this._scope = scope;
|
||||
},
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user