diff --git a/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl b/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl index c9efbca1aaa0..3bb920f4e4b9 100644 --- a/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl +++ b/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl @@ -13,6 +13,12 @@ interface mozIExtensionServiceWorkerInfo : nsISupports readonly attribute AString scriptURL; readonly attribute AString clientInfoId; }; + +[scriptable, builtinclass, uuid(e68e3c19-1b35-4112-8faa-5c5b84086a5b)] +interface mozIExtensionEventListener : nsISupports +{ + void callListener(in Array args); +}; [scriptable, builtinclass, uuid(0fee1c8f-e363-46a6-bd0c-d3c3338e2534)] interface mozIExtensionAPIRequest : nsISupports @@ -53,6 +59,9 @@ interface mozIExtensionAPIRequest : nsISupports // Set for requests coming from an extension service worker. readonly attribute mozIExtensionServiceWorkerInfo serviceWorkerInfo; + + // Set for `addListener`/`removeListener` API requests. + readonly attribute mozIExtensionEventListener eventListener; }; [scriptable, uuid(59fd4097-d88e-40fd-8664-fedd8ab67ab6)] diff --git a/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.cpp b/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.cpp index a5d856cf549f..b17776b33ee1 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.cpp +++ b/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.cpp @@ -56,6 +56,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionAPIRequest) NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionAPIRequest) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ExtensionAPIRequest) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSWInfo) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -65,6 +66,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ExtensionAPIRequest) NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ExtensionAPIRequest) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventListener) NS_IMPL_CYCLE_COLLECTION_UNLINK(mSWInfo) tmp->mStack.setUndefined(); tmp->mArgs.setUndefined(); @@ -200,5 +202,13 @@ ExtensionAPIRequest::GetServiceWorkerInfo( return NS_OK; } +NS_IMETHODIMP +ExtensionAPIRequest::GetEventListener(mozIExtensionEventListener** aListener) { + MOZ_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG_POINTER(aListener); + NS_IF_ADDREF(*aListener = mEventListener); + return NS_OK; +} + } // namespace extensions } // namespace mozilla diff --git a/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.h b/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.h index 9eee70e49516..c2355372b71b 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.h +++ b/toolkit/components/extensions/webidl-api/ExtensionAPIRequest.h @@ -7,6 +7,8 @@ #ifndef mozilla_extensions_ExtensionAPIRequest_h #define mozilla_extensions_ExtensionAPIRequest_h +#include "ExtensionEventListener.h" + #include "mozIExtensionAPIRequestHandling.h" #include "mozilla/HoldDropJSObjects.h" #include "mozilla/dom/ClientInfo.h" @@ -82,11 +84,17 @@ class ExtensionAPIRequest : public mozIExtensionAPIRequest { bool ShouldHaveResult() const { return ShouldHaveResult(mRequestType); } + void SetEventListener(const RefPtr& aListener) { + MOZ_ASSERT(!mEventListener); + mEventListener = aListener; + } + private: virtual ~ExtensionAPIRequest() { mSWClientInfo = Nothing(); mArgs.setUndefined(); mStack.setUndefined(); + mEventListener = nullptr; mozilla::DropJSObjects(this); }; @@ -96,6 +104,9 @@ class ExtensionAPIRequest : public mozIExtensionAPIRequest { JS::Heap mArgs; Maybe mSWClientInfo; RefPtr mSWInfo; + + // Only set for addListener/removeListener API requests. + RefPtr mEventListener; }; } // namespace extensions diff --git a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp index 740d3eebfa9d..653ae945bb9b 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp +++ b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ExtensionAPIRequestForwarder.h" +#include "ExtensionEventListener.h" #include "js/Promise.h" #include "mozilla/dom/Client.h" @@ -251,6 +252,7 @@ RequestWorkerRunnable::RequestWorkerRunnable( void RequestWorkerRunnable::Init(nsIGlobalObject* aGlobal, JSContext* aCx, const dom::Sequence& aArgs, + ExtensionEventListener* aListener, ErrorResult& aRv) { MOZ_ASSERT(dom::IsCurrentThreadRunningWorker()); @@ -274,6 +276,7 @@ void RequestWorkerRunnable::Init(nsIGlobalObject* aGlobal, JSContext* aCx, } SerializeCallerStack(aCx); + mEventListener = aListener; } void RequestWorkerRunnable::Init(nsIGlobalObject* aGlobal, JSContext* aCx, @@ -289,7 +292,7 @@ void RequestWorkerRunnable::Init(nsIGlobalObject* aGlobal, JSContext* aCx, ExtensionAPIRequestStructuredCloneWrite, }; - Init(aGlobal, aCx, aArgs, aRv); + Init(aGlobal, aCx, aArgs, /* aListener */ nullptr, aRv); if (aRv.Failed()) { return; } @@ -378,6 +381,11 @@ already_AddRefed RequestWorkerRunnable::CreateAPIRequest( RefPtr request = new ExtensionAPIRequest( mOuterRequest->GetRequestType(), *mOuterRequest->GetRequestTarget()); request->Init(mClientInfo, callArgs, callerStackValue); + + if (mEventListener) { + request->SetEventListener(mEventListener.forget()); + } + return request.forget(); } diff --git a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h index 81bc57f765d4..4eb8a9712aae 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h +++ b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h @@ -83,7 +83,8 @@ class ExtensionAPIRequestForwarder { private: already_AddRefed CreateAPIRequest( nsIGlobalObject* aGlobal, JSContext* aCx, - const dom::Sequence& aArgs, ErrorResult& aRv); + const dom::Sequence& aArgs, ExtensionEventListener* aListener, + ErrorResult& aRv); APIRequestType mRequestType; ExtensionAPIRequestTarget mRequestTarget; @@ -113,8 +114,28 @@ class RequestWorkerRunnable : public dom::WorkerMainThreadRunnable { RequestWorkerRunnable(dom::WorkerPrivate* aWorkerPrivate, ExtensionAPIRequestForwarder* aOuterAPIRequest); + /** + * Init a request runnable for AddListener and RemoveListener API requests + * (which do have an event callback callback and do not expect any return + * value). + */ void Init(nsIGlobalObject* aGlobal, JSContext* aCx, - const dom::Sequence& aArgs, ErrorResult& aRv); + const dom::Sequence& aArgs, + ExtensionEventListener* aListener, ErrorResult& aRv); + + /** + * Init a request runnable for CallFunctionNoReturn API requests (which do + * do not expect any return value). + */ + void Init(nsIGlobalObject* aGlobal, JSContext* aCx, + const dom::Sequence& aArgs, ErrorResult& aRv) { + Init(aGlobal, aCx, aArgs, nullptr, aRv); + } + + /** + * Init a request runnable for CallAsyncFunction API requests (which do + * expect a promise as return value). + */ void Init(nsIGlobalObject* aGlobal, JSContext* aCx, const dom::Sequence& aArgs, const RefPtr& aPromiseRetval, ErrorResult& aRv); @@ -150,6 +171,9 @@ class RequestWorkerRunnable : public dom::WorkerMainThreadRunnable { Maybe> mStackHolder; Maybe mClientInfo; + // Only set for addListener/removeListener API requests. + RefPtr mEventListener; + // The outer request object is kept alive by the caller for the // entire life of the inner worker runnable. ExtensionAPIRequestForwarder* mOuterRequest; diff --git a/toolkit/components/extensions/webidl-api/ExtensionEventListener.cpp b/toolkit/components/extensions/webidl-api/ExtensionEventListener.cpp new file mode 100644 index 000000000000..1ffeab5d894d --- /dev/null +++ b/toolkit/components/extensions/webidl-api/ExtensionEventListener.cpp @@ -0,0 +1,20 @@ +/* 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 "ExtensionEventListener.h" + +#include "nsThreadManager.h" // NS_IsMainThread + +namespace mozilla { +namespace extensions { + +NS_IMETHODIMP ExtensionEventListener::CallListener( + const nsTArray& aArgs) { + MOZ_ASSERT(NS_IsMainThread()); + return NS_ERROR_NOT_IMPLEMENTED; +} + +} // namespace extensions +} // namespace mozilla diff --git a/toolkit/components/extensions/webidl-api/ExtensionEventListener.h b/toolkit/components/extensions/webidl-api/ExtensionEventListener.h new file mode 100644 index 000000000000..4eaac47a8858 --- /dev/null +++ b/toolkit/components/extensions/webidl-api/ExtensionEventListener.h @@ -0,0 +1,29 @@ +/* -*- 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_extensions_ExtensionEventListener_h +#define mozilla_extensions_ExtensionEventListener_h + +#include "mozIExtensionAPIRequestHandling.h" + +namespace mozilla { +namespace extensions { + +// A class that represents a callback parameter (passed to addListener / +// removeListener), instances of this class are received by the +// mozIExtensionAPIRequestHandler as a property of the mozIExtensionAPIRequest. +// The mozIExtensionEventListener xpcom interface provides methods that allow +// the mozIExtensionAPIRequestHandler running in the Main Thread to call the +// underlying callback Function on its owning thread. +class ExtensionEventListener : public mozIExtensionEventListener { + public: + NS_DECL_MOZIEXTENSIONEVENTLISTENER +}; + +} // namespace extensions +} // namespace mozilla + +#endif // mozilla_extensions_ExtensionEventListener_h diff --git a/toolkit/components/extensions/webidl-api/moz.build b/toolkit/components/extensions/webidl-api/moz.build index f7e51cbe2278..5ff9ea8fea22 100644 --- a/toolkit/components/extensions/webidl-api/moz.build +++ b/toolkit/components/extensions/webidl-api/moz.build @@ -12,6 +12,7 @@ UNIFIED_SOURCES += [ "ExtensionAPIRequest.cpp", "ExtensionAPIRequestForwarder.cpp", "ExtensionBrowser.cpp", + "ExtensionEventListener.cpp", "ExtensionEventManager.cpp", ]