diff --git a/toolkit/components/extensions/Extension.jsm b/toolkit/components/extensions/Extension.jsm index 7cf5105814bb..456a1f94f429 100644 --- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -147,6 +147,7 @@ const CHILD_SHUTDOWN_TIMEOUT_MS = 8000; // Permissions that are only available to privileged extensions. const PRIVILEGED_PERMS = new Set([ + "activityLog", "mozillaAddons", "geckoViewAddons", "telemetry", diff --git a/toolkit/components/extensions/ext-toolkit.json b/toolkit/components/extensions/ext-toolkit.json index 01a8f40d0679..c7d98a3c9a77 100644 --- a/toolkit/components/extensions/ext-toolkit.json +++ b/toolkit/components/extensions/ext-toolkit.json @@ -82,6 +82,14 @@ ["extension"] ] }, + "activityLog": { + "url": "chrome://extensions/content/parent/ext-activityLog.js", + "schema": "chrome://extensions/content/schemas/activity_log.json", + "scopes": ["addon_parent"], + "paths": [ + ["activityLog"] + ] + }, "i18n": { "url": "chrome://extensions/content/parent/ext-i18n.js", "schema": "chrome://extensions/content/schemas/i18n.json", diff --git a/toolkit/components/extensions/jar.mn b/toolkit/components/extensions/jar.mn index 0279d8b2e1a6..c23f5ce9d8b6 100644 --- a/toolkit/components/extensions/jar.mn +++ b/toolkit/components/extensions/jar.mn @@ -7,6 +7,7 @@ toolkit.jar: content/extensions/dummy.xul content/extensions/ext-browser-content.js content/extensions/ext-toolkit.json + content/extensions/parent/ext-activityLog.js (parent/ext-activityLog.js) content/extensions/parent/ext-alarms.js (parent/ext-alarms.js) content/extensions/parent/ext-backgroundPage.js (parent/ext-backgroundPage.js) content/extensions/parent/ext-browserSettings.js (parent/ext-browserSettings.js) diff --git a/toolkit/components/extensions/parent/ext-activityLog.js b/toolkit/components/extensions/parent/ext-activityLog.js new file mode 100644 index 000000000000..2cd2801199c8 --- /dev/null +++ b/toolkit/components/extensions/parent/ext-activityLog.js @@ -0,0 +1,38 @@ +/* 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/. */ +"use strict"; + +ChromeUtils.defineModuleGetter( + this, + "ExtensionCommon", + "resource://gre/modules/ExtensionCommon.jsm" +); +ChromeUtils.defineModuleGetter( + this, + "ExtensionActivityLog", + "resource://gre/modules/ExtensionActivityLog.jsm" +); + +this.activityLog = class extends ExtensionAPI { + getAPI(context) { + return { + activityLog: { + onExtensionActivity: new ExtensionCommon.EventManager({ + context, + name: "activityLog.onExtensionActivity", + register: (fire, id) => { + function handler(details) { + fire.async(details); + } + + ExtensionActivityLog.addListener(id, handler); + return () => { + ExtensionActivityLog.removeListener(id, handler); + }; + }, + }).api(), + }, + }; + } +}; diff --git a/toolkit/components/extensions/schemas/activity_log.json b/toolkit/components/extensions/schemas/activity_log.json new file mode 100644 index 000000000000..a09187ee9f80 --- /dev/null +++ b/toolkit/components/extensions/schemas/activity_log.json @@ -0,0 +1,87 @@ +[ + { + "namespace": "manifest", + "types": [{ + "$extend": "Permission", + "choices": [{ + "type": "string", + "enum": [ + "activityLog" + ] + }] + }] + }, + { + "namespace": "activityLog", + "description": "Monitor extension activity", + "permissions": ["activityLog"], + "events": [ + { + "name": "onExtensionActivity", + "description": "Receives an activityItem for each logging event.", + "type": "function", + "parameters": [ + { + "name": "details", + "type": "object", + "properties": { + "timeStamp": { + "$ref": "extensionTypes.Date", + "description": "The date string when this call is triggered." + }, + "type": { + "type": "string", + "enum": ["api_call", "api_event", "content_script", "user_script"], + "description": "The type of log entry. api_call is a function call made by the extension and api_event is an event callback to the extension. content_script is logged when a content script is injected." + }, + "viewType": { + "type": "string", + "optional": true, + "enum": ["background", "popup", "sidebar", "tab", "devtools_page", "devtools_panel"], + "description": "The type of view where the activity occurred. Content scripts will not have a viewType." + }, + "name": { + "type": "string", + "description": "The name of the api call or event, or the script url if this is a content or user script event." + }, + "data": { + "type": "object", + "properties": { + "args": { + "type": "array", + "optional": true, + "items": { + "type": "any" + }, + "description": "A list of arguments passed to the call." + }, + "result": { + "type": "object", + "optional": true, + "description": "The result of the call." + }, + "tabId": { + "type": "integer", + "optional": true, + "description": "The tab associated with this event if it is a tab or content script." + }, + "url": { + "type": "string", + "optional": true, + "description": "If the type is content_script, this is the url of the script that was injected." + } + } + } + } + } + ], + "extraParameters": [ + { + "name": "id", + "type": "string" + } + ] + } + ] + } +] diff --git a/toolkit/components/extensions/schemas/jar.mn b/toolkit/components/extensions/schemas/jar.mn index f897860d2fa1..d66d537968d0 100644 --- a/toolkit/components/extensions/schemas/jar.mn +++ b/toolkit/components/extensions/schemas/jar.mn @@ -4,6 +4,7 @@ toolkit.jar: % content extensions %content/extensions/ + content/extensions/schemas/activity_log.json content/extensions/schemas/alarms.json content/extensions/schemas/browser_settings.json #ifndef ANDROID diff --git a/toolkit/components/extensions/test/mochitest/mochitest-common.ini b/toolkit/components/extensions/test/mochitest/mochitest-common.ini index 5b7607ab06c1..f991466a5161 100644 --- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini +++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini @@ -61,6 +61,7 @@ prefs = browser.chrome.guess_favicon=true skip-if = toolkit == 'android' && !is_fennec +[test_ext_activityLog.html] [test_ext_async_clipboard.html] skip-if = fission || toolkit == 'android' # near-permafail after landing bug 1270059: Bug 1523131 [test_ext_background_canvas.html] diff --git a/toolkit/components/extensions/test/mochitest/test_ext_activityLog.html b/toolkit/components/extensions/test/mochitest/test_ext_activityLog.html new file mode 100644 index 000000000000..5561c0f23ff5 --- /dev/null +++ b/toolkit/components/extensions/test/mochitest/test_ext_activityLog.html @@ -0,0 +1,290 @@ + + + + WebExtension activityLog test + + + + + + + + + + + diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_activityLog.js b/toolkit/components/extensions/test/xpcshell/test_ext_activityLog.js new file mode 100644 index 000000000000..4a23b6526461 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_activityLog.js @@ -0,0 +1,21 @@ +"use strict"; + +add_task(async function test_api_restricted() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + applications: { + gecko: { id: "activityLog-permission@tests.mozilla.org" }, + }, + permissions: ["activityLog"], + }, + async background() { + browser.test.assertEq( + undefined, + browser.activityLog, + "activityLog is privileged" + ); + }, + }); + await extension.startup(); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_permissions.js b/toolkit/components/extensions/test/xpcshell/test_ext_permissions.js index 208fc11c7dc1..c546cb10bbfa 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_permissions.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_permissions.js @@ -566,6 +566,7 @@ const GRANTED_WITHOUT_USER_PROMPT = [ "contextMenus", "contextualIdentities", "cookies", + "activityLog", "geckoProfiler", "identity", "idle", diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini index 6515dc0589af..3e9bcd64512e 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini @@ -1,5 +1,6 @@ [test_ext_MessageManagerProxy.js] skip-if = os == 'android' # Bug 1545439 +[test_ext_activityLog.js] [test_ext_alarms.js] [test_ext_alarms_does_not_fire.js] [test_ext_alarms_periodic.js]