From a881d0f446183abc6d1cf5825e7632478f07558c Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Mon, 14 Feb 2022 23:07:45 +0000 Subject: [PATCH] Bug 1753939 - [remote] Do not create message handlers for webextension contexts r=webdriver-reviewers,rpl,whimboo Differential Revision: https://phabricator.services.mozilla.com/D138523 --- .../browser_session_data_browser_element.js | 64 ++++++++++++++----- .../messagehandler/test/browser/head.js | 49 ++++++++++++++ .../modules/windowglobal/command.jsm | 6 +- .../MessageHandlerFrameActor.jsm | 1 + 4 files changed, 102 insertions(+), 18 deletions(-) diff --git a/remote/shared/messagehandler/test/browser/browser_session_data_browser_element.js b/remote/shared/messagehandler/test/browser/browser_session_data_browser_element.js index 8af5d59e5358..207b76c466db 100644 --- a/remote/shared/messagehandler/test/browser/browser_session_data_browser_element.js +++ b/remote/shared/messagehandler/test/browser/browser_session_data_browser_element.js @@ -8,17 +8,39 @@ const TEST_PAGE = "https://example.com/document-builder.sjs?html=tab"; /** * Check that message handlers are not created for parent process browser * elements, even if they have the type="content" attribute (eg used for the - * DevTools toolbox). + * DevTools toolbox), as well as for webextension contexts. */ add_task(async function test_session_data_broadcast() { + // Prepare: + // - one content tab + // - one browser type content + // - one browser type chrome + // - one sidebar webextension + // We only expect session data to be applied to the content tab const tab1 = BrowserTestUtils.addTab(gBrowser, TEST_PAGE); const contentBrowser1 = tab1.linkedBrowser; await BrowserTestUtils.browserLoaded(contentBrowser1); const parentBrowser1 = createParentBrowserElement(tab1, "content"); const parentBrowser2 = createParentBrowserElement(tab1, "chrome"); + const { + extension: extension1, + sidebarBrowser: extSidebarBrowser1, + } = await installSidebarExtension(); const root = createRootMessageHandler("session-id-event"); + // When the windowglobal command.jsm module applies the session data + // browser_session_data_browser_element, it will emit an internal event. + // Collect the events to detect which MessageHandlers have been started. + info("Watch internal events emitted when session data is applied"); + const sessionDataEvents = []; + const onRootEvent = function(evtName, wrappedEvt) { + if (wrappedEvt.name === "received-session-data") { + sessionDataEvents.push(wrappedEvt.data.contextId); + } + }; + root.on("message-handler-event", onRootEvent); + info("Add a new session data item, expect one return value"); await root.addSessionData({ moduleName: "command", @@ -29,12 +51,17 @@ add_task(async function test_session_data_broadcast() { values: [true], }); + function hasSessionData(browsingContext) { + return sessionDataEvents.includes(browsingContext.id); + } + info( "Check that only the content tab window global received the session data" ); - is(await hasSessionDataFlag(contentBrowser1), true); - is(await hasSessionDataFlag(parentBrowser1), undefined); - is(await hasSessionDataFlag(parentBrowser2), undefined); + is(hasSessionData(contentBrowser1.browsingContext), true); + is(hasSessionData(parentBrowser1.browsingContext), false); + is(hasSessionData(parentBrowser2.browsingContext), false); + is(hasSessionData(extSidebarBrowser1.browsingContext), false); const tab2 = BrowserTestUtils.addTab(gBrowser, TEST_PAGE); const contentBrowser2 = tab2.linkedBrowser; @@ -42,23 +69,30 @@ add_task(async function test_session_data_broadcast() { const parentBrowser3 = createParentBrowserElement(contentBrowser2, "content"); const parentBrowser4 = createParentBrowserElement(contentBrowser2, "chrome"); + const { + extension: extension2, + sidebarBrowser: extSidebarBrowser2, + } = await installSidebarExtension(); + info("Wait until the session data was applied to the new tab"); - await SpecialPowers.spawn(contentBrowser2, [], async () => { - await ContentTaskUtils.waitForCondition(() => content.hasSessionDataFlag); - }); + await TestUtils.waitForCondition(() => + sessionDataEvents.includes(contentBrowser2.browsingContext.id) + ); info("Check that parent browser elements did not apply the session data"); - is(await hasSessionDataFlag(parentBrowser3), undefined); - is(await hasSessionDataFlag(parentBrowser4), undefined); + is(hasSessionData(parentBrowser3.browsingContext), false); + is(hasSessionData(parentBrowser4.browsingContext), false); + + info( + "Check that extension did not apply the session data, " + + extSidebarBrowser2.browsingContext.id + ); + is(hasSessionData(extSidebarBrowser2.browsingContext), false); root.destroy(); gBrowser.removeTab(tab1); gBrowser.removeTab(tab2); + await extension1.unload(); + await extension2.unload(); }); - -function hasSessionDataFlag(browser) { - return SpecialPowers.spawn(browser, [], () => { - return content.hasSessionDataFlag; - }); -} diff --git a/remote/shared/messagehandler/test/browser/head.js b/remote/shared/messagehandler/test/browser/head.js index 0d0d80fec7f7..ef8f11b440fc 100644 --- a/remote/shared/messagehandler/test/browser/head.js +++ b/remote/shared/messagehandler/test/browser/head.js @@ -113,3 +113,52 @@ function createTestMarkupWithFrames() { TEST_URI_MARKUP )}`; } + +/** + * Install a sidebar extension. + * + * @return {Object} + * Return value with two properties: + * - extension: test wrapper as returned by SpecialPowers.loadExtension. + * Make sure to explicitly call extension.unload() before the end of the test. + * - sidebarBrowser: the browser element containing the extension sidebar. + */ +async function installSidebarExtension() { + info("Load the test extension"); + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + sidebar_action: { + default_panel: "sidebar.html", + }, + }, + useAddonManager: "temporary", + + files: { + "sidebar.html": ` + + + Test extension + + + `, + "sidebar.js": function() { + browser.test.sendMessage("sidebar-loaded", { + bcId: SpecialPowers.wrap(window).browsingContext.id, + }); + }, + }, + }); + + info("Wait for the extension to start"); + await extension.startup(); + + info("Wait for the extension browsing context"); + const { bcId } = await extension.awaitMessage("sidebar-loaded"); + const sidebarBrowser = BrowsingContext.get(bcId).top.embedderElement; + ok(sidebarBrowser, "Got a browser element for the extension sidebar"); + + return { + extension, + sidebarBrowser, + }; +} diff --git a/remote/shared/messagehandler/test/browser/resources/modules/windowglobal/command.jsm b/remote/shared/messagehandler/test/browser/resources/modules/windowglobal/command.jsm index d925412998d4..02347871924a 100644 --- a/remote/shared/messagehandler/test/browser/resources/modules/windowglobal/command.jsm +++ b/remote/shared/messagehandler/test/browser/resources/modules/windowglobal/command.jsm @@ -41,9 +41,9 @@ class Command extends Module { } if (params.category === "browser_session_data_browser_element") { - BrowsingContext.get( - this.messageHandler.contextId - ).window.hasSessionDataFlag = true; + this.emitEvent("received-session-data", { + contextId: this.messageHandler.contextId, + }); } return {}; diff --git a/remote/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm b/remote/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm index b4ec56098f13..30342df7a833 100644 --- a/remote/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm +++ b/remote/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm @@ -30,6 +30,7 @@ const FRAME_ACTOR_CONFIG = { }, }, allFrames: true, + messageManagerGroups: ["browsers"], }; /**