Bug 1688040 - part7.1: Added WebIDL-based binding for the browser.runtime WebExtensions API. r=baku

Differential Revision: https://phabricator.services.mozilla.com/D106700
This commit is contained in:
Luca Greco 2021-10-05 17:05:41 +00:00
Родитель 364e863da1
Коммит eead64213b
14 изменённых файлов: 362 добавлений и 28 удалений

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

@ -1612,6 +1612,11 @@ DOMInterfaces = {
'nativeType': 'mozilla::extensions::ExtensionPort',
},
'ExtensionRuntime': {
'headerFile': 'mozilla/extensions/ExtensionRuntime.h',
'nativeType': 'mozilla::extensions::ExtensionRuntime',
},
'ExtensionTest': {
'headerFile': 'mozilla/extensions/ExtensionTest.h',
'nativeType': 'mozilla::extensions::ExtensionTest',

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

@ -34,7 +34,12 @@ interface ExtensionBrowser {
[Replaceable, SameObject, BinaryName="GetExtensionAlarms",
Func="mozilla::extensions::ExtensionAlarms::IsAllowed"]
readonly attribute ExtensionAlarms alarms;
// `browser.runtime` API namespace
[Replaceable, SameObject, BinaryName="GetExtensionRuntime",
Func="mozilla::extensions::ExtensionRuntime::IsAllowed"]
readonly attribute ExtensionRuntime runtime;
// `browser.test` API namespace, available in tests.
[Replaceable, SameObject, BinaryName="GetExtensionTest",
Func="mozilla::extensions::ExtensionTest::IsAllowed"]

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

@ -0,0 +1,91 @@
/*
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT
*
* The content of this file has been generated based on the WebExtensions API
* JSONSchema using the following command:
*
* export SCRIPT_DIR="toolkit/components/extensions/webidl-api"
* mach python $SCRIPT_DIR/GenerateWebIDLBindings.py -- runtime
*
* More info about generating webidl API bindings for WebExtensions API at:
*
* https://firefox-source-docs.mozilla.org/toolkit/components/extensions/webextensions/webidl_bindings.html
*/
/* 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/.
*
* You are granted a license to use, reproduce and create derivative works of
* this document.
*/
// WebIDL definition for the "runtime" WebExtensions API
[Exposed=(ServiceWorker), LegacyNoInterfaceObject]
interface ExtensionRuntime {
// API methods.
[Throws, WebExtensionStub="Async"]
any openOptionsPage(optional Function callback);
[Throws, WebExtensionStub]
any getManifest();
[Throws, WebExtensionStub="ReturnsString"]
DOMString getURL(DOMString path);
[Throws, WebExtensionStub="Async"]
any setUninstallURL(optional DOMString url, optional Function callback);
[Throws, WebExtensionStub="NoReturn"]
void reload();
[Throws, WebExtensionStub="ReturnsPort"]
ExtensionPort connect(optional DOMString extensionId, optional any connectInfo);
[Throws, WebExtensionStub="ReturnsPort"]
ExtensionPort connectNative(DOMString application);
[Throws, WebExtensionStub="AsyncAmbiguous"]
any sendMessage(any... args);
[Throws, WebExtensionStub="Async"]
any sendNativeMessage(DOMString application, any message, optional Function responseCallback);
[Throws, WebExtensionStub="Async"]
any getBrowserInfo(optional Function callback);
[Throws, WebExtensionStub="Async"]
any getPlatformInfo(optional Function callback);
// API events.
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onStartup;
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onInstalled;
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onUpdateAvailable;
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onConnect;
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onConnectExternal;
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onMessage;
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onMessageExternal;
// API properties.
[Replaceable]
readonly attribute any lastError;
[Replaceable]
readonly attribute DOMString id;
};

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

@ -1064,6 +1064,7 @@ WEBIDL_FILES += [
# ExtensionMockAPI is not a real WebExtensions API, and it is only enabled in tests.
"ExtensionMockAPI.webidl",
"ExtensionPort.webidl",
"ExtensionRuntime.webidl",
"ExtensionTest.webidl",
]

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

@ -12,6 +12,7 @@
#include "ExtensionAPICallSyncFunction.h"
#include "ExtensionAPIGetProperty.h"
#include "ExtensionEventManager.h"
#include "ExtensionPort.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/SerializedStackHolder.h"
@ -100,6 +101,55 @@ void ExtensionAPIBase::CallWebExtMethod(JSContext* aCx,
}
}
void ExtensionAPIBase::CallWebExtMethodReturnsString(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs, nsAString& aRetVal,
ErrorResult& aRv) {
JS::Rooted<JS::Value> retval(aCx);
auto request = CallSyncFunction(aApiMethod);
request->Run(GetGlobalObject(), aCx, aArgs, &retval, aRv);
if (aRv.Failed()) {
return;
}
if (NS_WARN_IF(!retval.isString())) {
ThrowUnexpectedError(aCx, aRv);
return;
}
nsAutoJSString str;
if (!str.init(aCx, retval.toString())) {
JS_ClearPendingException(aCx);
ThrowUnexpectedError(aCx, aRv);
return;
}
aRetVal = str;
}
already_AddRefed<ExtensionPort> ExtensionAPIBase::CallWebExtMethodReturnsPort(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs, ErrorResult& aRv) {
JS::Rooted<JS::Value> apiResult(aCx);
auto request = CallSyncFunction(aApiMethod);
request->Run(GetGlobalObject(), aCx, aArgs, &apiResult, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
IgnoredErrorResult rv;
RefPtr<ExtensionPort> port =
ExtensionPort::Create(GetGlobalObject(), 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.
ThrowUnexpectedError(aCx, aRv);
return nullptr;
}
return port.forget();
}
void ExtensionAPIBase::CallWebExtMethodAsyncInternal(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs,

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

@ -27,6 +27,7 @@ class ExtensionAPICallSyncFunction;
class ExtensionAPICallAsyncFunction;
class ExtensionAPIGetProperty;
class ExtensionEventManager;
class ExtensionPort;
class ExtensionAPIBase {
protected:
@ -70,6 +71,15 @@ class ExtensionAPIBase {
JS::MutableHandle<JS::Value> aRetVal,
ErrorResult& aRv);
virtual void CallWebExtMethodReturnsString(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs, nsAString& aRetVal,
ErrorResult& aRv);
virtual already_AddRefed<ExtensionPort> CallWebExtMethodReturnsPort(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs, ErrorResult& aRv);
virtual void CallWebExtMethodAsync(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs,

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

@ -10,6 +10,7 @@
#include "mozilla/dom/WorkerPrivate.h" // GetWorkerPrivateFromContext
#include "mozilla/extensions/ExtensionAlarms.h"
#include "mozilla/extensions/ExtensionMockAPI.h"
#include "mozilla/extensions/ExtensionRuntime.h"
#include "mozilla/extensions/ExtensionTest.h"
#include "mozilla/extensions/WebExtensionPolicy.h"
@ -20,7 +21,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionBrowser);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionBrowser, mGlobal,
mExtensionAlarms, mExtensionMockAPI,
mExtensionTest);
mExtensionRuntime, mExtensionTest);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionBrowser)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -88,6 +89,14 @@ ExtensionMockAPI* ExtensionBrowser::GetExtensionMockAPI() {
return mExtensionMockAPI;
}
ExtensionRuntime* ExtensionBrowser::GetExtensionRuntime() {
if (!mExtensionRuntime) {
mExtensionRuntime = new ExtensionRuntime(mGlobal, this);
}
return mExtensionRuntime;
}
ExtensionTest* ExtensionBrowser::GetExtensionTest() {
if (!mExtensionTest) {
mExtensionTest = new ExtensionTest(mGlobal, this);

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

@ -21,6 +21,7 @@ namespace extensions {
class ExtensionAlarms;
class ExtensionMockAPI;
class ExtensionRuntime;
class ExtensionTest;
bool ExtensionAPIAllowed(JSContext* aCx, JSObject* aGlobal);
@ -29,6 +30,7 @@ class ExtensionBrowser final : public nsISupports, public nsWrapperCache {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionAlarms> mExtensionAlarms;
RefPtr<ExtensionMockAPI> mExtensionMockAPI;
RefPtr<ExtensionRuntime> mExtensionRuntime;
RefPtr<ExtensionTest> mExtensionTest;
~ExtensionBrowser() = default;
@ -46,6 +48,7 @@ class ExtensionBrowser final : public nsISupports, public nsWrapperCache {
ExtensionAlarms* GetExtensionAlarms();
ExtensionMockAPI* GetExtensionMockAPI();
ExtensionRuntime* GetExtensionRuntime();
ExtensionTest* GetExtensionTest();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS

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

@ -87,27 +87,5 @@ ExtensionEventManager* ExtensionMockAPI::OnTestEvent() {
return mOnTestEventMgr;
}
already_AddRefed<ExtensionPort> ExtensionMockAPI::CallWebExtMethodReturnsPort(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs, ErrorResult& aRv) {
JS::Rooted<JS::Value> apiResult(aCx);
auto request = CallSyncFunction(u"methodReturnsPort"_ns);
request->Run(mGlobal, aCx, aArgs, &apiResult, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
IgnoredErrorResult rv;
RefPtr<ExtensionPort> port = ExtensionPort::Create(mGlobal, 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.
ThrowUnexpectedError(aCx, aRv);
return nullptr;
}
return port.forget();
}
} // namespace extensions
} // namespace mozilla

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

@ -60,10 +60,6 @@ class ExtensionMockAPI final : public nsISupports,
JS::MutableHandle<JS::Value> aRetval);
void GetPropertyAsString(DOMString& aRetval);
already_AddRefed<ExtensionPort> CallWebExtMethodReturnsPort(
JSContext* aCx, const nsAString& aApiMethod,
const dom::Sequence<JS::Value>& aArgs, ErrorResult& aRv);
ExtensionEventManager* OnTestEvent();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS

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

@ -0,0 +1,102 @@
/* 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 "ExtensionRuntime.h"
#include "ExtensionEventManager.h"
#include "mozilla/dom/ExtensionRuntimeBinding.h"
#include "nsIGlobalObject.h"
namespace mozilla {
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);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionRuntime)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ExtensionRuntime::ExtensionRuntime(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser)
: mGlobal(aGlobal) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
}
/* static */
bool ExtensionRuntime::IsAllowed(JSContext* aCx, JSObject* aGlobal) {
return true;
}
JSObject* ExtensionRuntime::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::ExtensionRuntime_Binding::Wrap(aCx, this, aGivenProto);
}
nsIGlobalObject* ExtensionRuntime::GetParentObject() const { return mGlobal; }
ExtensionEventManager* ExtensionRuntime::OnStartup() {
if (!mOnStartupEventMgr) {
mOnStartupEventMgr = CreateEventManager(u"onStartup"_ns);
}
return mOnStartupEventMgr;
}
ExtensionEventManager* ExtensionRuntime::OnInstalled() {
if (!mOnInstalledEventMgr) {
mOnInstalledEventMgr = CreateEventManager(u"onInstalled"_ns);
}
return mOnInstalledEventMgr;
}
ExtensionEventManager* ExtensionRuntime::OnUpdateAvailable() {
if (!mOnUpdateAvailableEventMgr) {
mOnUpdateAvailableEventMgr = CreateEventManager(u"onUpdateAvailable"_ns);
}
return mOnUpdateAvailableEventMgr;
}
ExtensionEventManager* ExtensionRuntime::OnConnect() {
if (!mOnConnectEventMgr) {
mOnConnectEventMgr = CreateEventManager(u"onConnect"_ns);
}
return mOnConnectEventMgr;
}
ExtensionEventManager* ExtensionRuntime::OnConnectExternal() {
if (!mOnConnectExternalEventMgr) {
mOnConnectExternalEventMgr = CreateEventManager(u"onConnectExternal"_ns);
}
return mOnConnectExternalEventMgr;
}
ExtensionEventManager* ExtensionRuntime::OnMessage() {
if (!mOnMessageEventMgr) {
mOnMessageEventMgr = CreateEventManager(u"onMessage"_ns);
}
return mOnMessageEventMgr;
}
ExtensionEventManager* ExtensionRuntime::OnMessageExternal() {
if (!mOnMessageExternalEventMgr) {
mOnMessageExternalEventMgr = CreateEventManager(u"onMessageExternal"_ns);
}
return mOnMessageExternalEventMgr;
}
} // namespace extensions
} // namespace mozilla

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

@ -0,0 +1,79 @@
/* -*- 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_ExtensionRuntime_h
#define mozilla_extensions_ExtensionRuntime_h
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsCycleCollectionParticipant.h"
#include "nsCOMPtr.h"
#include "nsISupports.h"
#include "nsWrapperCache.h"
#include "ExtensionAPIBase.h"
#include "ExtensionBrowser.h"
class nsIGlobalObject;
namespace mozilla {
namespace extensions {
class ExtensionEventManager;
class ExtensionRuntime final : public nsISupports,
public nsWrapperCache,
public ExtensionAPINamespace {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionEventManager> mOnStartupEventMgr;
RefPtr<ExtensionEventManager> mOnInstalledEventMgr;
RefPtr<ExtensionEventManager> mOnUpdateAvailableEventMgr;
RefPtr<ExtensionEventManager> mOnConnectEventMgr;
RefPtr<ExtensionEventManager> mOnConnectExternalEventMgr;
RefPtr<ExtensionEventManager> mOnMessageEventMgr;
RefPtr<ExtensionEventManager> mOnMessageExternalEventMgr;
~ExtensionRuntime() = default;
public:
ExtensionRuntime(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser);
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
nsString GetAPINamespace() const override { return u"runtime"_ns; }
// nsWrapperCache interface methods
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// DOM bindings methods
static bool IsAllowed(JSContext* aCx, JSObject* aGlobal);
nsIGlobalObject* GetParentObject() const;
ExtensionEventManager* OnStartup();
ExtensionEventManager* OnInstalled();
ExtensionEventManager* OnUpdateAvailable();
ExtensionEventManager* OnConnect();
ExtensionEventManager* OnConnectExternal();
ExtensionEventManager* OnMessage();
ExtensionEventManager* OnMessageExternal();
void GetLastError(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval) {}
void GetId(nsString& aRetval) {}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ExtensionRuntime)
};
} // namespace extensions
} // namespace mozilla
#endif // mozilla_extensions_ExtensionRuntime_h

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

@ -48,6 +48,9 @@ WEBEXT_TYPES_MAPPING = {
#
# NOTE: Please keep this table in alphabetic order.
WEBEXT_STUBS_MAPPING = {
"runtime.connect": "ReturnsPort",
"runtime.connectNative": "ReturnsPort",
"runtime.getURL": "ReturnsString",
"test.assertEq": "NotImplementedNoReturn",
"test.assertRejects": "NotImplementedAsync",
"test.assertThrows": "NotImplementedNoReturn",

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

@ -28,11 +28,13 @@ EXPORTS.mozilla.extensions += [
# WebExtensions API namespaces.
UNIFIED_SOURCES += [
"ExtensionAlarms.cpp",
"ExtensionRuntime.cpp",
"ExtensionTest.cpp",
]
EXPORTS.mozilla.extensions += [
"ExtensionAlarms.h",
"ExtensionRuntime.h",
"ExtensionTest.h",
]