Bug 1688040 - part9: Implement setting/clearing and reporting browser.runtime.lastError from ChromeCompatCallbackHandler::RejectedCallback. r=baku

This patch does:
- add to ExtensionBrowser two new data members to keep track of value for the browser.runtime.lastError and if it was checked while
  the chrome compatible callback was being executed
- add to ExtensionBrowser 3 new methods to set, get and clear the lastError value
- add a reference to the ExtensionBrowser to all API namespaces and API objects classes, because it has to be then propagated to the
  ChromeCompatCallbackHandler instances that are being attached to the promise result of the async API methods calls if the caller did
  pass the optional callback parameter
- tweak the ChromeCompatCallbackHandler class to set the lastError value before calling the callback in ChromeCompatCallbackHAndler::RejectedCallback
  and then clear it after the call has been completed and report it to the console if it wasn't checked
- change the ExtensionRuntime::GetLastError methhod to restrieve and return the value from the ExtensionBrowser instance

Differential Revision: https://phabricator.services.mozilla.com/D107327
This commit is contained in:
Luca Greco 2021-10-06 12:28:23 +00:00
Родитель 7105532924
Коммит 7b70ba9812
20 изменённых файлов: 234 добавлений и 52 удалений

Просмотреть файл

@ -421,3 +421,6 @@ ElementSetCaptureWarning=Element.setCapture() is deprecated. Use Element.setPoin
ElementReleaseCaptureWarning=Element.releaseCapture() is deprecated. Use Element.releasePointerCapture() instead. For more help https://developer.mozilla.org/docs/Web/API/Element/releasePointerCapture
# LOCALIZATION NOTE: Do not translate "Document.releaseCapture()" and "Element.releasePointerCapture()".
DocumentReleaseCaptureWarning=Document.releaseCapture() is deprecated. Use Element.releasePointerCapture() instead. For more help https://developer.mozilla.org/docs/Web/API/Element/releasePointerCapture
# LOCALIZATION NOTE: Don't translate browser.runtime.lastError, %S is the error message from the unchecked value set on browser.runtime.lastError.
WebExtensionUncheckedLastError=browser.runtime.lastError value was not checked: %S

Просмотреть файл

@ -365,3 +365,33 @@ add_task(async function test_sw_api_request_bgsw_runtime_onConnect() {
await extPage.close();
await extension.unload();
});
add_task(async function test_sw_runtime_lastError() {
const extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
background: {
service_worker: "sw.js",
},
applications: { gecko: { id: "test-bg-sw@mochi.test" } },
},
files: {
"page.html": "<!DOCTYPE html><body></body>",
"sw.js": async function() {
browser.runtime.sendMessage(() => {
const lastError = browser.runtime.lastError;
if (!(lastError instanceof Error)) {
browser.test.fail(
`lastError isn't an Error instance: ${lastError}`
);
}
browser.test.sendMessage("test-lastError-completed");
});
},
},
});
await extension.startup();
await extension.awaitMessage("test-lastError-completed");
await extension.unload();
});

Просмотреть файл

@ -11,9 +11,11 @@
#include "ExtensionAPICallFunctionNoReturn.h"
#include "ExtensionAPICallSyncFunction.h"
#include "ExtensionAPIGetProperty.h"
#include "ExtensionBrowser.h"
#include "ExtensionEventManager.h"
#include "ExtensionPort.h"
#include "mozilla/ConsoleReportCollector.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/SerializedStackHolder.h"
#include "mozilla/dom/FunctionBinding.h"
@ -29,12 +31,14 @@ NS_IMPL_ISUPPORTS0(ChromeCompatCallbackHandler)
// static
void ChromeCompatCallbackHandler::Create(
dom::Promise* aPromise, const RefPtr<dom::Function>& aCallback) {
ExtensionBrowser* aExtensionBrowser, dom::Promise* aPromise,
const RefPtr<dom::Function>& aCallback) {
MOZ_ASSERT(aPromise);
MOZ_ASSERT(aExtensionBrowser);
MOZ_ASSERT(aCallback);
RefPtr<ChromeCompatCallbackHandler> handler =
new ChromeCompatCallbackHandler(aCallback);
new ChromeCompatCallbackHandler(aExtensionBrowser, aCallback);
aPromise->AppendNativeHandler(handler);
}
@ -53,7 +57,37 @@ void ChromeCompatCallbackHandler::RejectedCallback(
// Call the chrome-compatible callback without any parameter, the errors
// isn't passed to the callback as a parameter but the extension will be
// able to retrieve it from chrome.runtime.lastError.
mExtensionBrowser->SetLastError(aValue);
MOZ_KnownLive(mCallback)->Call({}, &retval, rv);
if (mExtensionBrowser->ClearLastError()) {
ReportUncheckedLastError(aCx, aValue);
}
}
void ChromeCompatCallbackHandler::ReportUncheckedLastError(
JSContext* aCx, JS::Handle<JS::Value> aValue) {
nsCString sourceSpec;
uint32_t line = 0;
uint32_t column = 0;
nsString valueString;
nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column,
valueString);
nsTArray<nsString> params;
params.AppendElement(valueString);
RefPtr<ConsoleReportCollector> reporter = new ConsoleReportCollector();
reporter->AddConsoleReport(nsIScriptError::errorFlag, "content javascript"_ns,
nsContentUtils::eDOM_PROPERTIES, sourceSpec, line,
column, "WebExtensionUncheckedLastError"_ns,
params);
dom::WorkerPrivate* workerPrivate = dom::GetWorkerPrivateFromContext(aCx);
RefPtr<Runnable> r = NS_NewRunnableFunction(
"ChromeCompatCallbackHandler::ReportUncheckedLastError",
[reporter]() { reporter->FlushReportsToConsole(0); });
workerPrivate->DispatchToMainThread(r.forget());
}
// WebExtensionStub methods shared between multiple API namespaces.
@ -138,8 +172,8 @@ already_AddRefed<ExtensionPort> ExtensionAPIBase::CallWebExtMethodReturnsPort(
}
IgnoredErrorResult rv;
RefPtr<ExtensionPort> port =
ExtensionPort::Create(GetGlobalObject(), apiResult, rv);
RefPtr<ExtensionPort> port = ExtensionPort::Create(
GetGlobalObject(), GetExtensionBrowser(), apiResult, rv);
if (NS_WARN_IF(rv.Failed())) {
// ExtensionPort::Create doesn't throw the js exception with the generic
// error message as the "api request forwarding" helper classes.
@ -173,7 +207,8 @@ void ExtensionAPIBase::CallWebExtMethodAsyncInternal(
// The async method has been called with the chrome-compatible callback
// convention.
if (aCallback) {
ChromeCompatCallbackHandler::Create(domPromise, aCallback);
ChromeCompatCallbackHandler::Create(GetExtensionBrowser(), domPromise,
aCallback);
return;
}
@ -261,8 +296,8 @@ void ExtensionAPIBase::GetWebExtPropertyAsJSValue(
already_AddRefed<ExtensionEventManager> ExtensionAPIBase::CreateEventManager(
const nsAString& aEventName) {
RefPtr<ExtensionEventManager> eventMgr = new ExtensionEventManager(
GetGlobalObject(), GetAPINamespace(), aEventName, GetAPIObjectType(),
GetAPIObjectId());
GetGlobalObject(), GetExtensionBrowser(), GetAPINamespace(), aEventName,
GetAPIObjectType(), GetAPIObjectId());
return eventMgr.forget();
}

Просмотреть файл

@ -26,12 +26,14 @@ class ExtensionAPICallFunctionNoReturn;
class ExtensionAPICallSyncFunction;
class ExtensionAPICallAsyncFunction;
class ExtensionAPIGetProperty;
class ExtensionBrowser;
class ExtensionEventManager;
class ExtensionPort;
class ExtensionAPIBase {
protected:
virtual nsIGlobalObject* GetGlobalObject() const = 0;
virtual ExtensionBrowser* GetExtensionBrowser() const = 0;
virtual nsString GetAPINamespace() const = 0;
virtual nsString GetAPIObjectType() const = 0;
virtual nsString GetAPIObjectId() const = 0;
@ -133,7 +135,8 @@ class ChromeCompatCallbackHandler final : public dom::PromiseNativeHandler {
public:
NS_DECL_THREADSAFE_ISUPPORTS
static void Create(dom::Promise* aPromise,
static void Create(ExtensionBrowser* aExtensionBrowser,
dom::Promise* aPromise,
const RefPtr<dom::Function>& aCallback);
MOZ_CAN_RUN_SCRIPT void ResolvedCallback(
@ -142,14 +145,19 @@ class ChromeCompatCallbackHandler final : public dom::PromiseNativeHandler {
JSContext* aCx, JS::Handle<JS::Value> aValue) override;
private:
explicit ChromeCompatCallbackHandler(const RefPtr<dom::Function>& aCallback)
: mCallback(aCallback) {
ChromeCompatCallbackHandler(ExtensionBrowser* aExtensionBrowser,
const RefPtr<dom::Function>& aCallback)
: mCallback(aCallback), mExtensionBrowser(aExtensionBrowser) {
MOZ_ASSERT(aCallback);
MOZ_ASSERT(aExtensionBrowser);
}
~ChromeCompatCallbackHandler() = default;
void ReportUncheckedLastError(JSContext* aCx, JS::Handle<JS::Value> aValue);
RefPtr<dom::Function> mCallback;
RefPtr<ExtensionBrowser> mExtensionBrowser;
};
} // namespace extensions

Просмотреть файл

@ -15,7 +15,7 @@ namespace extensions {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionAlarms);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionAlarms)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionAlarms, mGlobal,
mOnAlarmEventMgr);
mExtensionBrowser, mOnAlarmEventMgr);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionAlarms)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -24,8 +24,9 @@ NS_INTERFACE_MAP_END
ExtensionAlarms::ExtensionAlarms(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser)
: mGlobal(aGlobal) {
: mGlobal(aGlobal), mExtensionBrowser(aExtensionBrowser) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
MOZ_DIAGNOSTIC_ASSERT(mExtensionBrowser);
}
/* static */

Просмотреть файл

@ -30,6 +30,7 @@ class ExtensionAlarms final : public nsISupports,
public nsWrapperCache,
public ExtensionAPINamespace {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionBrowser> mExtensionBrowser;
RefPtr<ExtensionEventManager> mOnAlarmEventMgr;
~ExtensionAlarms() = default;
@ -41,6 +42,10 @@ class ExtensionAlarms final : public nsISupports,
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
ExtensionBrowser* GetExtensionBrowser() const override {
return mExtensionBrowser;
}
nsString GetAPINamespace() const override { return u"alarms"_ns; }
// nsWrapperCache interface methods

Просмотреть файл

@ -17,17 +17,38 @@
namespace mozilla {
namespace extensions {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionBrowser);
NS_IMPL_CYCLE_COLLECTION_CLASS(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionBrowser, mGlobal,
mExtensionAlarms, mExtensionMockAPI,
mExtensionRuntime, mExtensionTest);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionBrowser)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExtensionAlarms)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExtensionMockAPI)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExtensionRuntime)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExtensionTest)
tmp->mLastError.setUndefined();
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExtensionAlarms)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExtensionMockAPI)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExtensionRuntime)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExtensionTest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLastError)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
ExtensionBrowser::ExtensionBrowser(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
@ -73,6 +94,22 @@ bool ExtensionAPIAllowed(JSContext* aCx, JSObject* aGlobal) {
#endif
}
void ExtensionBrowser::SetLastError(JS::Handle<JS::Value> aLastError) {
mLastError.set(aLastError);
mCheckedLastError = false;
}
void ExtensionBrowser::GetLastError(JS::MutableHandle<JS::Value> aRetVal) {
aRetVal.set(mLastError);
mCheckedLastError = true;
}
bool ExtensionBrowser::ClearLastError() {
bool shouldReport = !mCheckedLastError;
mLastError.setUndefined();
return shouldReport;
}
ExtensionAlarms* ExtensionBrowser::GetExtensionAlarms() {
if (!mExtensionAlarms) {
mExtensionAlarms = new ExtensionAlarms(mGlobal, this);

Просмотреть файл

@ -28,6 +28,8 @@ bool ExtensionAPIAllowed(JSContext* aCx, JSObject* aGlobal);
class ExtensionBrowser final : public nsISupports, public nsWrapperCache {
nsCOMPtr<nsIGlobalObject> mGlobal;
JS::Heap<JS::Value> mLastError;
bool mCheckedLastError;
RefPtr<ExtensionAlarms> mExtensionAlarms;
RefPtr<ExtensionMockAPI> mExtensionMockAPI;
RefPtr<ExtensionRuntime> mExtensionRuntime;
@ -38,6 +40,16 @@ class ExtensionBrowser final : public nsISupports, public nsWrapperCache {
public:
explicit ExtensionBrowser(nsIGlobalObject* aGlobal);
// Helpers used for the expected behavior of the browser.runtime.lastError
// and browser.extension.lastError.
void SetLastError(JS::Handle<JS::Value> aLastError);
void GetLastError(JS::MutableHandle<JS::Value> aRetVal);
// ClearLastError is used by ChromeCompatCallbackHandler::RejectedCallback
// to clear the lastError property. When this method returns true the
// caller will know that the error value wasn't checked by the callback and
// should be reported to the console
bool ClearLastError();
// nsWrapperCache interface methods
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;

Просмотреть файл

@ -164,11 +164,12 @@ NS_IMPL_ISUPPORTS(ExtensionEventListener, mozIExtensionEventListener)
// static
already_AddRefed<ExtensionEventListener> ExtensionEventListener::Create(
nsIGlobalObject* aGlobal, dom::Function* aCallback,
CleanupCallback&& aCleanupCallback, ErrorResult& aRv) {
nsIGlobalObject* aGlobal, ExtensionBrowser* aExtensionBrowser,
dom::Function* aCallback, CleanupCallback&& aCleanupCallback,
ErrorResult& aRv) {
MOZ_ASSERT(dom::IsCurrentThreadRunningWorker());
RefPtr<ExtensionEventListener> extCb =
new ExtensionEventListener(aGlobal, aCallback);
new ExtensionEventListener(aGlobal, aExtensionBrowser, aCallback);
auto* workerPrivate = dom::GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
@ -335,6 +336,11 @@ bool ExtensionListenerCallWorkerRunnable::WorkerRun(
return true;
}
RefPtr<ExtensionBrowser> extensionBrowser = mListener->GetExtensionBrowser();
if (NS_WARN_IF(!extensionBrowser)) {
return true;
}
auto fn = mListener->GetCallback();
if (NS_WARN_IF(!fn)) {
return true;
@ -397,8 +403,8 @@ bool ExtensionListenerCallWorkerRunnable::WorkerRun(
// until we will need to expect it to support other object types that
// some specific API may need.
MOZ_ASSERT(mAPIObjectType == APIObjectType::RUNTIME_PORT);
RefPtr<ExtensionPort> port =
ExtensionPort::Create(global, apiObjectDescriptor, rv);
RefPtr<ExtensionPort> port = ExtensionPort::Create(global, extensionBrowser,
apiObjectDescriptor, rv);
if (NS_WARN_IF(rv.Failed())) {
retPromise->MaybeReject(rv.StealNSResult());
return true;

Просмотреть файл

@ -46,8 +46,9 @@ class ExtensionEventListener final : public mozIExtensionEventListener {
using CallbackType = ListenerCallOptions::CallbackType;
static already_AddRefed<ExtensionEventListener> Create(
nsIGlobalObject* aGlobal, dom::Function* aCallback,
CleanupCallback&& aCleanupCallback, ErrorResult& aRv);
nsIGlobalObject* aGlobal, ExtensionBrowser* aExtensionBrowser,
dom::Function* aCallback, CleanupCallback&& aCleanupCallback,
ErrorResult& aRv);
static bool IsPromise(JSContext* aCx, JS::Handle<JS::Value> aValue) {
if (!aValue.isObject()) {
@ -67,6 +68,8 @@ class ExtensionEventListener final : public mozIExtensionEventListener {
return global;
}
ExtensionBrowser* GetExtensionBrowser() const { return mExtensionBrowser; }
void Cleanup() {
if (mWorkerRef) {
MutexAutoLock lock(mMutex);
@ -77,13 +80,21 @@ class ExtensionEventListener final : public mozIExtensionEventListener {
mGlobal = nullptr;
mCallback = nullptr;
mExtensionBrowser = nullptr;
}
private:
ExtensionEventListener(nsIGlobalObject* aGlobal, dom::Function* aCallback)
ExtensionEventListener(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser,
dom::Function* aCallback)
: mGlobal(do_GetWeakReference(aGlobal)),
mExtensionBrowser(aExtensionBrowser),
mCallback(aCallback),
mMutex("ExtensionEventListener::mMutex"){};
mMutex("ExtensionEventListener::mMutex") {
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(aExtensionBrowser);
MOZ_ASSERT(aCallback);
};
static UniquePtr<dom::StructuredCloneHolder> SerializeCallArguments(
const nsTArray<JS::Value>& aArgs, JSContext* aCx, ErrorResult& aRv);
@ -95,6 +106,7 @@ class ExtensionEventListener final : public mozIExtensionEventListener {
// Accessed only on the owning thread.
nsWeakPtr mGlobal;
RefPtr<ExtensionBrowser> mExtensionBrowser;
RefPtr<dom::Function> mCallback;
// Used to make sure we are not going to release the

Просмотреть файл

@ -19,11 +19,13 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionEventManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ExtensionEventManager)
tmp->mListeners.clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ExtensionEventManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ExtensionEventManager)
@ -38,17 +40,18 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionEventManager)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ExtensionEventManager::ExtensionEventManager(nsIGlobalObject* aGlobal,
const nsAString& aNamespace,
const nsAString& aEventName,
const nsAString& aObjectType,
const nsAString& aObjectId)
ExtensionEventManager::ExtensionEventManager(
nsIGlobalObject* aGlobal, ExtensionBrowser* aExtensionBrowser,
const nsAString& aNamespace, const nsAString& aEventName,
const nsAString& aObjectType, const nsAString& aObjectId)
: mGlobal(aGlobal),
mExtensionBrowser(aExtensionBrowser),
mAPINamespace(aNamespace),
mEventName(aEventName),
mAPIObjectType(aObjectType),
mAPIObjectId(aObjectId) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
MOZ_DIAGNOSTIC_ASSERT(mExtensionBrowser);
RefPtr<ExtensionEventManager> self = this;
mozilla::HoldJSObjects(this);
@ -93,7 +96,7 @@ void ExtensionEventManager::AddListener(
IgnoredErrorResult rv;
RefPtr<ExtensionEventListener> wrappedCb = ExtensionEventListener::Create(
mGlobal, &aCallback,
mGlobal, mExtensionBrowser, &aCallback,
[self = std::move(self)]() { self->ReleaseListeners(); }, rv);
if (NS_WARN_IF(rv.Failed())) {

Просмотреть файл

@ -38,6 +38,7 @@ class ExtensionEventManager final : public nsISupports,
public nsWrapperCache,
public ExtensionAPIBase {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionBrowser> mExtensionBrowser;
nsString mAPINamespace;
nsString mEventName;
nsString mAPIObjectType;
@ -57,6 +58,9 @@ class ExtensionEventManager final : public nsISupports,
protected:
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
ExtensionBrowser* GetExtensionBrowser() const override {
return mExtensionBrowser;
}
nsString GetAPINamespace() const override { return mAPINamespace; }
@ -65,7 +69,9 @@ class ExtensionEventManager final : public nsISupports,
nsString GetAPIObjectId() const override { return mAPIObjectId; }
public:
ExtensionEventManager(nsIGlobalObject* aGlobal, const nsAString& aNamespace,
ExtensionEventManager(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser,
const nsAString& aNamespace,
const nsAString& aEventName,
const nsAString& aObjectType = VoidString(),
const nsAString& aObjectId = VoidString());

Просмотреть файл

@ -16,7 +16,7 @@ namespace extensions {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionMockAPI);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionMockAPI)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionMockAPI, mGlobal,
mOnTestEventMgr);
mExtensionBrowser, mOnTestEventMgr);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionMockAPI)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -25,8 +25,9 @@ NS_INTERFACE_MAP_END
ExtensionMockAPI::ExtensionMockAPI(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser)
: mGlobal(aGlobal) {
: mGlobal(aGlobal), mExtensionBrowser(aExtensionBrowser) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
MOZ_DIAGNOSTIC_ASSERT(mExtensionBrowser);
}
/* static */

Просмотреть файл

@ -33,6 +33,7 @@ class ExtensionMockAPI final : public nsISupports,
public nsWrapperCache,
public ExtensionAPINamespace {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionBrowser> mExtensionBrowser;
RefPtr<ExtensionEventManager> mOnTestEventMgr;
~ExtensionMockAPI() = default;
@ -41,6 +42,10 @@ class ExtensionMockAPI final : public nsISupports,
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
ExtensionBrowser* GetExtensionBrowser() const override {
return mExtensionBrowser;
}
nsString GetAPINamespace() const override { return u"mockExtensionAPI"_ns; }
public:

Просмотреть файл

@ -16,7 +16,7 @@ namespace extensions {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionPort);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionPort)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionPort, mGlobal,
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionPort, mGlobal, mExtensionBrowser,
mOnDisconnectEventMgr,
mOnMessageEventMgr);
@ -27,8 +27,8 @@ NS_INTERFACE_MAP_END
// static
already_AddRefed<ExtensionPort> ExtensionPort::Create(
nsIGlobalObject* aGlobal, JS::Handle<JS::Value> aDescriptorValue,
ErrorResult& aRv) {
nsIGlobalObject* aGlobal, ExtensionBrowser* aExtensionBrowser,
JS::Handle<JS::Value> aDescriptorValue, ErrorResult& aRv) {
if (!aDescriptorValue.isObject()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
@ -43,15 +43,18 @@ already_AddRefed<ExtensionPort> ExtensionPort::Create(
}
RefPtr<ExtensionPort> port =
new ExtensionPort(aGlobal, std::move(portDescriptor));
new ExtensionPort(aGlobal, aExtensionBrowser, std::move(portDescriptor));
return port.forget();
}
ExtensionPort::ExtensionPort(
nsIGlobalObject* aGlobal,
nsIGlobalObject* aGlobal, ExtensionBrowser* aExtensionBrowser,
UniquePtr<dom::ExtensionPortDescriptor> aPortDescriptor)
: mGlobal(aGlobal), mPortDescriptor(std::move(aPortDescriptor)) {
: mGlobal(aGlobal),
mExtensionBrowser(aExtensionBrowser),
mPortDescriptor(std::move(aPortDescriptor)) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
MOZ_DIAGNOSTIC_ASSERT(mExtensionBrowser);
}
nsString ExtensionPort::GetAPIObjectId() const {

Просмотреть файл

@ -31,18 +31,23 @@ class ExtensionPort final : public nsISupports,
public nsWrapperCache,
public ExtensionAPIBase {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionBrowser> mExtensionBrowser;
RefPtr<ExtensionEventManager> mOnDisconnectEventMgr;
RefPtr<ExtensionEventManager> mOnMessageEventMgr;
UniquePtr<dom::ExtensionPortDescriptor> mPortDescriptor;
~ExtensionPort() = default;
ExtensionPort(nsIGlobalObject* aGlobal,
ExtensionPort(nsIGlobalObject* aGlobal, ExtensionBrowser* aExtensionBrowser,
UniquePtr<dom::ExtensionPortDescriptor> aPortDescriptor);
protected:
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
ExtensionBrowser* GetExtensionBrowser() const override {
return mExtensionBrowser;
}
nsString GetAPINamespace() const override { return u"runtime"_ns; }
nsString GetAPIObjectType() const override { return u"Port"_ns; }
@ -51,8 +56,8 @@ class ExtensionPort final : public nsISupports,
public:
static already_AddRefed<ExtensionPort> Create(
nsIGlobalObject* aGlobal, JS::Handle<JS::Value> aDescriptorValue,
ErrorResult& aRv);
nsIGlobalObject* aGlobal, ExtensionBrowser* aExtensionBrowser,
JS::Handle<JS::Value> aDescriptorValue, ErrorResult& aRv);
// nsWrapperCache interface methods
JSObject* WrapObject(JSContext* aCx,

Просмотреть файл

@ -15,9 +15,9 @@ namespace extensions {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionRuntime);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionRuntime)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(
ExtensionRuntime, mGlobal, mOnStartupEventMgr, mOnInstalledEventMgr,
mOnUpdateAvailableEventMgr, mOnConnectEventMgr, mOnConnectExternalEventMgr,
mOnMessageEventMgr, mOnMessageExternalEventMgr);
ExtensionRuntime, mGlobal, mExtensionBrowser, mOnStartupEventMgr,
mOnInstalledEventMgr, mOnUpdateAvailableEventMgr, mOnConnectEventMgr,
mOnConnectExternalEventMgr, mOnMessageEventMgr, mOnMessageExternalEventMgr);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionRuntime)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -26,8 +26,9 @@ NS_INTERFACE_MAP_END
ExtensionRuntime::ExtensionRuntime(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser)
: mGlobal(aGlobal) {
: mGlobal(aGlobal), mExtensionBrowser(aExtensionBrowser) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
MOZ_DIAGNOSTIC_ASSERT(mExtensionBrowser);
}
/* static */
@ -44,9 +45,7 @@ nsIGlobalObject* ExtensionRuntime::GetParentObject() const { return mGlobal; }
void ExtensionRuntime::GetLastError(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval) {
// TODO: special case this, using
// GetWebExtPropertyAsErrorObject(aCx, u"lastError"_ns, aRetval);
// doesn't seem a good solution nor an easy one in this case.
mExtensionBrowser->GetLastError(aRetval);
}
void ExtensionRuntime::GetId(DOMString& aRetval) {

Просмотреть файл

@ -30,6 +30,7 @@ class ExtensionRuntime final : public nsISupports,
public nsWrapperCache,
public ExtensionAPINamespace {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionBrowser> mExtensionBrowser;
RefPtr<ExtensionEventManager> mOnStartupEventMgr;
RefPtr<ExtensionEventManager> mOnInstalledEventMgr;
RefPtr<ExtensionEventManager> mOnUpdateAvailableEventMgr;
@ -47,6 +48,10 @@ class ExtensionRuntime final : public nsISupports,
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
ExtensionBrowser* GetExtensionBrowser() const override {
return mExtensionBrowser;
}
nsString GetAPINamespace() const override { return u"runtime"_ns; }
// nsWrapperCache interface methods

Просмотреть файл

@ -20,7 +20,7 @@ bool IsInAutomation(JSContext* aCx, JSObject* aGlobal) {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionTest);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionTest)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionTest, mGlobal,
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionTest, mGlobal, mExtensionBrowser,
mOnMessageEventMgr);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionTest)
@ -30,8 +30,9 @@ NS_INTERFACE_MAP_END
ExtensionTest::ExtensionTest(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser)
: mGlobal(aGlobal) {
: mGlobal(aGlobal), mExtensionBrowser(aExtensionBrowser) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
MOZ_DIAGNOSTIC_ASSERT(mExtensionBrowser);
}
/* static */

Просмотреть файл

@ -32,6 +32,7 @@ class ExtensionTest final : public nsISupports,
public nsWrapperCache,
public ExtensionAPINamespace {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionBrowser> mExtensionBrowser;
RefPtr<ExtensionEventManager> mOnMessageEventMgr;
~ExtensionTest() = default;
@ -42,6 +43,10 @@ class ExtensionTest final : public nsISupports,
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
ExtensionBrowser* GetExtensionBrowser() const override {
return mExtensionBrowser;
}
nsString GetAPINamespace() const override { return u"test"_ns; }
// nsWrapperCache interface methods