Bug 1688040 - part5: Added WebIDL-based binding for the browser.alarms WebExtensions API. r=baku

Differential Revision: https://phabricator.services.mozilla.com/D102928
This commit is contained in:
Luca Greco 2021-10-06 12:28:20 +00:00
parent ce341c641b
commit a73062e1f9
10 changed files with 239 additions and 1 deletions

View File

@ -1617,6 +1617,11 @@ DOMInterfaces = {
'nativeType': 'mozilla::extensions::ExtensionTest',
},
'ExtensionAlarms': {
'headerFile': 'mozilla/extensions/ExtensionAlarms.h',
'nativeType': 'mozilla::extensions::ExtensionAlarms',
},
####################################
# Test Interfaces of various sorts #
####################################

View File

@ -0,0 +1,47 @@
/*
* 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 -- alarms
*
* 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 "alarms" WebExtensions API
[Exposed=(ServiceWorker), LegacyNoInterfaceObject]
interface ExtensionAlarms {
// API methods.
[Throws, WebExtensionStub="NoReturn"]
void create(optional DOMString name, any alarmInfo);
[Throws, WebExtensionStub="Async"]
any get(optional DOMString name, optional Function callback);
[Throws, WebExtensionStub="Async"]
any getAll(optional Function callback);
[Throws, WebExtensionStub="Async"]
any clear(optional DOMString name, optional Function callback);
[Throws, WebExtensionStub="Async"]
any clearAll(optional Function callback);
// API events.
[Replaceable, SameObject]
readonly attribute ExtensionEventManager onAlarm;
};

View File

@ -30,6 +30,11 @@ interface ExtensionBrowser {
Pref="extensions.webidl-api.expose_mock_interface"]
readonly attribute ExtensionMockAPI mockExtensionAPI;
// `browser.alarms` API namespace
[Replaceable, SameObject, BinaryName="GetExtensionAlarms",
Func="mozilla::extensions::ExtensionAlarms::IsAllowed"]
readonly attribute ExtensionAlarms alarms;
// `browser.test` API namespace, available in tests.
[Replaceable, SameObject, BinaryName="GetExtensionTest",
Func="mozilla::extensions::ExtensionTest::IsAllowed"]

View File

@ -1058,6 +1058,7 @@ WEBIDL_FILES += [
# WebExtensions API.
WEBIDL_FILES += [
"ExtensionAlarms.webidl",
"ExtensionBrowser.webidl",
"ExtensionEventManager.webidl",
# ExtensionMockAPI is not a real WebExtensions API, and it is only enabled in tests.

View File

@ -53,3 +53,50 @@ add_task(async function test_sw_api_request_handling_local_process_api() {
await extension.awaitFinish();
await extension.unload();
});
// Verify ExtensionAPIRequestHandler handling API requests for
// an ext-*.js API module running in the main process
// (toolkit/components/extensions/parent/ext-alarms.js).
add_task(async function test_sw_api_request_handling_main_process_api() {
const extension = ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {
background: {
service_worker: "sw.js",
},
permissions: ["alarms"],
applications: { gecko: { id: "test-bg-sw@mochi.test" } },
},
files: {
"page.html": "<!DOCTYPE html><body></body>",
"sw.js": async function() {
browser.alarms.create("test-alarm", { when: Date.now() + 2000000 });
const all = await browser.alarms.getAll();
if (all.length === 1 && all[0].name === "test-alarm") {
browser.test.succeed("Got the expected alarms");
} else {
browser.test.fail(
`browser.alarms.create didn't create the expected alarm: ${JSON.stringify(
all
)}`
);
}
browser.alarms.onAlarm.addListener(alarm => {
if (alarm.name === "test-onAlarm") {
browser.test.succeed("Got the expected onAlarm event");
} else {
browser.test.fail(`Got unexpected onAlarm event: ${alarm.name}`);
}
browser.test.sendMessage("test-completed");
});
browser.alarms.create("test-onAlarm", { when: Date.now() + 1000 });
},
},
});
await extension.startup();
await extension.awaitMessage("test-completed");
await extension.unload();
});

View File

@ -0,0 +1,54 @@
/* 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 "ExtensionAlarms.h"
#include "ExtensionEventManager.h"
#include "mozilla/dom/ExtensionAlarmsBinding.h"
#include "nsIGlobalObject.h"
namespace mozilla {
namespace extensions {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionAlarms);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionAlarms)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionAlarms, mGlobal,
mOnAlarmEventMgr);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionAlarms)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
ExtensionAlarms::ExtensionAlarms(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser)
: mGlobal(aGlobal) {
MOZ_DIAGNOSTIC_ASSERT(mGlobal);
}
/* static */
bool ExtensionAlarms::IsAllowed(JSContext* aCx, JSObject* aGlobal) {
// TODO(Bug 1725478): this API visibility should be gated by the "alarms"
// permission.
return true;
}
JSObject* ExtensionAlarms::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return dom::ExtensionAlarms_Binding::Wrap(aCx, this, aGivenProto);
}
nsIGlobalObject* ExtensionAlarms::GetParentObject() const { return mGlobal; }
ExtensionEventManager* ExtensionAlarms::OnAlarm() {
if (!mOnAlarmEventMgr) {
mOnAlarmEventMgr = CreateEventManager(u"onAlarm"_ns);
}
return mOnAlarmEventMgr;
}
} // namespace extensions
} // namespace mozilla

View File

@ -0,0 +1,64 @@
/* -*- 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_ExtensionAlarms_h
#define mozilla_extensions_ExtensionAlarms_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 ExtensionAlarms final : public nsISupports,
public nsWrapperCache,
public ExtensionAPINamespace {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionEventManager> mOnAlarmEventMgr;
~ExtensionAlarms() = default;
public:
ExtensionAlarms(nsIGlobalObject* aGlobal,
ExtensionBrowser* aExtensionBrowser);
// ExtensionAPIBase methods
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
nsString GetAPINamespace() const override { return u"alarms"_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* OnAlarm();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ExtensionAlarms)
};
} // namespace extensions
} // namespace mozilla
#endif // mozilla_extensions_ExtensionAlarms_h

View File

@ -8,6 +8,7 @@
#include "mozilla/dom/ExtensionBrowserBinding.h"
#include "mozilla/dom/WorkerPrivate.h" // GetWorkerPrivateFromContext
#include "mozilla/extensions/ExtensionAlarms.h"
#include "mozilla/extensions/ExtensionMockAPI.h"
#include "mozilla/extensions/ExtensionTest.h"
#include "mozilla/extensions/WebExtensionPolicy.h"
@ -18,7 +19,8 @@ namespace extensions {
NS_IMPL_CYCLE_COLLECTING_ADDREF(ExtensionBrowser);
NS_IMPL_CYCLE_COLLECTING_RELEASE(ExtensionBrowser)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ExtensionBrowser, mGlobal,
mExtensionMockAPI, mExtensionTest);
mExtensionAlarms, mExtensionMockAPI,
mExtensionTest);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ExtensionBrowser)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -70,6 +72,14 @@ bool ExtensionAPIAllowed(JSContext* aCx, JSObject* aGlobal) {
#endif
}
ExtensionAlarms* ExtensionBrowser::GetExtensionAlarms() {
if (!mExtensionAlarms) {
mExtensionAlarms = new ExtensionAlarms(mGlobal, this);
}
return mExtensionAlarms;
}
ExtensionMockAPI* ExtensionBrowser::GetExtensionMockAPI() {
if (!mExtensionMockAPI) {
mExtensionMockAPI = new ExtensionMockAPI(mGlobal, this);

View File

@ -19,6 +19,7 @@ class ErrorResult;
namespace extensions {
class ExtensionAlarms;
class ExtensionMockAPI;
class ExtensionTest;
@ -26,6 +27,7 @@ bool ExtensionAPIAllowed(JSContext* aCx, JSObject* aGlobal);
class ExtensionBrowser final : public nsISupports, public nsWrapperCache {
nsCOMPtr<nsIGlobalObject> mGlobal;
RefPtr<ExtensionAlarms> mExtensionAlarms;
RefPtr<ExtensionMockAPI> mExtensionMockAPI;
RefPtr<ExtensionTest> mExtensionTest;
@ -42,6 +44,7 @@ class ExtensionBrowser final : public nsISupports, public nsWrapperCache {
nsIGlobalObject* GetParentObject() const;
ExtensionAlarms* GetExtensionAlarms();
ExtensionMockAPI* GetExtensionMockAPI();
ExtensionTest* GetExtensionTest();

View File

@ -27,10 +27,12 @@ EXPORTS.mozilla.extensions += [
# WebExtensions API namespaces.
UNIFIED_SOURCES += [
"ExtensionAlarms.cpp",
"ExtensionTest.cpp",
]
EXPORTS.mozilla.extensions += [
"ExtensionAlarms.h",
"ExtensionTest.h",
]