From 320eb67200fffde07b8f017ea59f4d20984656f9 Mon Sep 17 00:00:00 2001 From: Tim Huang Date: Sat, 29 Jan 2022 09:38:40 +0000 Subject: [PATCH 1/6] Bug 1752581 - Transmit permissions for the partitioned principal during loading a channel into a content process. r=nika This patch makes ContentParent::AboutToLoadHttpFtpDocumentForChild() to also transmit permissions for the partitioned principal so that the web content principal can access permissions for partitioned principal. Differential Revision: https://phabricator.services.mozilla.com/D137307 --- dom/ipc/ContentParent.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index ca25998af9f8..57bd3b60b23f 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -5927,7 +5927,9 @@ nsresult ContentParent::AboutToLoadHttpFtpDocumentForChild( } nsCOMPtr principal; - rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(principal)); + nsCOMPtr partitionedPrincipal; + rv = ssm->GetChannelResultPrincipals(aChannel, getter_AddRefs(principal), + getter_AddRefs(partitionedPrincipal)); NS_ENSURE_SUCCESS(rv, rv); // Let the caller know we're going to send main thread IPC for updating @@ -5938,9 +5940,15 @@ nsresult ContentParent::AboutToLoadHttpFtpDocumentForChild( TransmitBlobURLsForPrincipal(principal); + // Tranmit permissions for both regular and partitioned principal so that the + // content process can get permissions for the partitioned principal. For + // example, the desk-notification permission for a partitioned service worker. rv = TransmitPermissionsForPrincipal(principal); NS_ENSURE_SUCCESS(rv, rv); + rv = TransmitPermissionsForPrincipal(partitionedPrincipal); + NS_ENSURE_SUCCESS(rv, rv); + nsLoadFlags newLoadFlags; aChannel->GetLoadFlags(&newLoadFlags); if (newLoadFlags & nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE) { From dfa71ba080783097e2eaf5eb82945ba5ff1f0f71 Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Sat, 29 Jan 2022 13:21:57 +0000 Subject: [PATCH 2/6] Bug 1752610 - Part 1: Cover more members in ReadableaByteStreamController cycle collection r=evilpie Differential Revision: https://phabricator.services.mozilla.com/D137330 --- dom/streams/ReadableByteStreamController.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dom/streams/ReadableByteStreamController.cpp b/dom/streams/ReadableByteStreamController.cpp index e34b21d29f68..444804281743 100644 --- a/dom/streams/ReadableByteStreamController.cpp +++ b/dom/streams/ReadableByteStreamController.cpp @@ -43,7 +43,8 @@ namespace dom { NS_IMPL_CYCLE_COLLECTION_CLASS(ReadableByteStreamController) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ReadableByteStreamController, ReadableStreamController) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mByobRequest, mStream) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mByobRequest, mCancelAlgorithm, + mPullAlgorithm, mStream) tmp->ClearPendingPullIntos(); tmp->ClearQueue(); NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER @@ -51,7 +52,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ReadableByteStreamController, ReadableStreamController) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mByobRequest, mStream) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mByobRequest, mCancelAlgorithm, + mPullAlgorithm, mStream) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ReadableByteStreamController, From edd26e9b389073d4199f7e0f73d85a76ca33335a Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Sat, 29 Jan 2022 13:21:58 +0000 Subject: [PATCH 3/6] Bug 1752610 - Part 2: Cover members in ReadableStreamBYOB* cycle collection r=evilpie Depends on D137330 Differential Revision: https://phabricator.services.mozilla.com/D137366 --- dom/streams/ReadableStreamBYOBReader.cpp | 11 +++-------- dom/streams/ReadableStreamBYOBRequest.cpp | 11 ++++++++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/dom/streams/ReadableStreamBYOBReader.cpp b/dom/streams/ReadableStreamBYOBReader.cpp index 52aee821fb9b..4358afa22a96 100644 --- a/dom/streams/ReadableStreamBYOBReader.cpp +++ b/dom/streams/ReadableStreamBYOBReader.cpp @@ -22,9 +22,9 @@ namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_INHERITED(ReadableStreamBYOBReader, - ReadableStreamGenericReader, - mReadIntoRequests) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_INHERITED(ReadableStreamBYOBReader, + ReadableStreamGenericReader, + mReadIntoRequests) NS_IMPL_ADDREF_INHERITED(ReadableStreamBYOBReader, ReadableStreamGenericReader) NS_IMPL_RELEASE_INHERITED(ReadableStreamBYOBReader, ReadableStreamGenericReader) @@ -32,11 +32,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ReadableStreamBYOBReader) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_END_INHERITING(ReadableStreamGenericReader) -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ReadableStreamBYOBReader, - ReadableStreamGenericReader) - NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_TRACE_END - JSObject* ReadableStreamBYOBReader::WrapObject( JSContext* aCx, JS::Handle aGivenProto) { return ReadableStreamBYOBReader_Binding::Wrap(aCx, this, aGivenProto); diff --git a/dom/streams/ReadableStreamBYOBRequest.cpp b/dom/streams/ReadableStreamBYOBRequest.cpp index 0c7b85564e36..03503b3637b7 100644 --- a/dom/streams/ReadableStreamBYOBRequest.cpp +++ b/dom/streams/ReadableStreamBYOBRequest.cpp @@ -30,7 +30,16 @@ ReadableStreamBYOBRequest::~ReadableStreamBYOBRequest() { mozilla::DropJSObjects(this); } -NS_IMPL_CYCLE_COLLECTION(ReadableStreamBYOBRequest) +NS_IMPL_CYCLE_COLLECTION_CLASS(ReadableStreamBYOBRequest) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ReadableStreamBYOBRequest) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal, mController) + tmp->mView = nullptr; + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ReadableStreamBYOBRequest) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal, mController) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + NS_IMPL_CYCLE_COLLECTING_ADDREF(ReadableStreamBYOBRequest) NS_IMPL_CYCLE_COLLECTING_RELEASE(ReadableStreamBYOBRequest) From 5763da85555a968e2739cf7b88ac331579ee988e Mon Sep 17 00:00:00 2001 From: Paul Zuehlcke Date: Sat, 29 Jan 2022 14:24:58 +0000 Subject: [PATCH 4/6] Bug 1749377 - Use prefersColorSchemeOverride to inherit dark PBM theme for prompts and pageInfo window. r=desktop-theme-reviewers,dao Differential Revision: https://phabricator.services.mozilla.com/D136931 --- browser/base/content/pageinfo/pageInfo.js | 13 +++++++++++++ .../components/prompts/content/commonDialog.js | 13 +++++++++++++ toolkit/modules/LightweightThemeConsumer.jsm | 15 +++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/browser/base/content/pageinfo/pageInfo.js b/browser/base/content/pageinfo/pageInfo.js index 05d23c768b02..ffb4a4a96105 100644 --- a/browser/base/content/pageinfo/pageInfo.js +++ b/browser/base/content/pageinfo/pageInfo.js @@ -13,6 +13,19 @@ XPCOMUtils.defineLazyModuleGetters(this, { E10SUtils: "resource://gre/modules/E10SUtils.jsm", }); +// Inherit color scheme overrides from parent window. This is to inherit the +// color scheme of dark themed PBM windows. +{ + let openerColorSchemeOverride = + window.opener?.browsingContext?.top.prefersColorSchemeOverride; + if ( + openerColorSchemeOverride && + window.browsingContext == window.browsingContext.top + ) { + window.browsingContext.prefersColorSchemeOverride = openerColorSchemeOverride; + } +} + // define a js object to implement nsITreeView function pageInfoTreeView(treeid, copycol) { // copycol is the index number for the column that we want to add to diff --git a/toolkit/components/prompts/content/commonDialog.js b/toolkit/components/prompts/content/commonDialog.js index c62530b16a41..97a432b32269 100644 --- a/toolkit/components/prompts/content/commonDialog.js +++ b/toolkit/components/prompts/content/commonDialog.js @@ -13,6 +13,19 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var propBag, args, Dialog; +// Inherit color scheme overrides from parent window. This is to inherit the +// color scheme of dark themed PBM windows. +{ + let openerColorSchemeOverride = + window.opener?.browsingContext?.top.prefersColorSchemeOverride; + if ( + openerColorSchemeOverride && + window.browsingContext == window.browsingContext.top + ) { + window.browsingContext.prefersColorSchemeOverride = openerColorSchemeOverride; + } +} + function commonDialogOnLoad() { propBag = window.arguments[0] .QueryInterface(Ci.nsIWritablePropertyBag2) diff --git a/toolkit/modules/LightweightThemeConsumer.jsm b/toolkit/modules/LightweightThemeConsumer.jsm index 5824e99ffdce..c23a16f37844 100644 --- a/toolkit/modules/LightweightThemeConsumer.jsm +++ b/toolkit/modules/LightweightThemeConsumer.jsm @@ -270,6 +270,21 @@ LightweightThemeConsumer.prototype = { return true; })(); + // If this is a per-window dark theme, set the color scheme override so + // child BrowsingContexts, such as embedded prompts, get themed + // appropriately. + // If not, reset the color scheme override field. This is required to reset + // the color scheme on theme switch. + if ( + useDarkTheme && + !updateGlobalThemeData && + this._win.browsingContext == this._win.browsingContext.top + ) { + this._win.browsingContext.prefersColorSchemeOverride = "dark"; + } else { + this._win.browsingContext.prefersColorSchemeOverride = "none"; + } + let theme = useDarkTheme ? themeData.darkTheme : themeData.theme; if (!theme) { theme = { id: DEFAULT_THEME_ID }; From 9a5b3ef76548fb7221b2d39eb66cc2df9927c25f Mon Sep 17 00:00:00 2001 From: Paul Zuehlcke Date: Sat, 29 Jan 2022 14:24:58 +0000 Subject: [PATCH 5/6] Bug 1749377 - Set color scheme on window widget to fix PBM dark theme issues on macOS. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D136933 --- layout/generic/nsContainerFrame.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index cf5905ec2437..7df20f052d10 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -777,6 +777,11 @@ void nsContainerFrame::SyncWindowProperties(nsPresContext* aPresContext, nsCOMPtr viewWidget = aView->GetWidget(); viewWidget->SetTransparencyMode(mode); windowWidget->SetWindowShadowStyle(shadow); + + // For macOS, apply color scheme overrides to the top level window widget. + if (auto scheme = aPresContext->GetOverriddenColorScheme()) { + windowWidget->SetColorScheme(scheme); + } } if (!aRC) return; From 8a4f73389e2cbbb2158862543d6d8c991252a01d Mon Sep 17 00:00:00 2001 From: Paul Zuehlcke Date: Sat, 29 Jan 2022 14:24:59 +0000 Subject: [PATCH 6/6] Bug 1749377 - Tests for dark pageInfo and prompts. r=dao Differential Revision: https://phabricator.services.mozilla.com/D136934 --- .../test/browser/browser_ext_themes_pbm.js | 155 ++++++++++++++++-- 1 file changed, 139 insertions(+), 16 deletions(-) diff --git a/toolkit/components/extensions/test/browser/browser_ext_themes_pbm.js b/toolkit/components/extensions/test/browser/browser_ext_themes_pbm.js index 144edba5fd94..894c8fff0f6f 100644 --- a/toolkit/components/extensions/test/browser/browser_ext_themes_pbm.js +++ b/toolkit/components/extensions/test/browser/browser_ext_themes_pbm.js @@ -9,12 +9,18 @@ const { BuiltInThemes } = ChromeUtils.import( "resource:///modules/BuiltInThemes.jsm" ); +const { PromptTestUtils } = ChromeUtils.import( + "resource://testing-common/PromptTestUtils.jsm" +); const IS_LINUX = AppConstants.platform == "linux"; const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org"; const DARK_THEME_ID = "firefox-compact-dark@mozilla.org"; +// This tests opens many chrome windows which is slow on debug builds. +requestLongerTimeout(2); + /** * Test a window's theme color scheme. * @param {*} options - Test options. @@ -58,6 +64,40 @@ async function testWindowColorScheme({ } } +/** + * Match the prefers-color-scheme media query and return the results. + * @param {Object} options + * @param {Window} options.win - If chrome=true, window to test, otherwise + * parent window of the content window to test. + * @param {boolean} options.chrome - If true the media queries will be matched + * against the supplied chrome window. Otherwise they will be matched against + * the content window. + * @returns {Promise<{light: boolean, dark: boolean}>} - Resolves with an + * object of the media query results. + */ +function getPrefersColorSchemeInfo({ win, chrome = false }) { + let fn = async windowObj => { + // If called in the parent, we use the supplied win object. Otherwise use + // the content window global. + let win = windowObj || content; + + // LookAndFeel updates are async. + await new Promise(resolve => { + win.requestAnimationFrame(() => win.requestAnimationFrame(resolve)); + }); + return { + light: win.matchMedia("(prefers-color-scheme: light)").matches, + dark: win.matchMedia("(prefers-color-scheme: dark)").matches, + }; + }; + + if (chrome) { + return fn(win); + } + + return SpecialPowers.spawn(win.gBrowser.selectedBrowser, [], fn); +} + add_task(async function setup() { // Set system theme to light to ensure consistency across test machines. await SpecialPowers.pushPrefEnv({ @@ -113,22 +153,7 @@ add_task(async function test_default_theme_light() { expectDefaultDarkAttribute: true, }); - let prefersColorScheme = await SpecialPowers.spawn( - pbmWindowA.gBrowser.selectedBrowser, - [], - async () => { - // LookAndFeel updates are async. - await new Promise(resolve => { - content.requestAnimationFrame(() => - content.requestAnimationFrame(resolve) - ); - }); - return { - light: content.matchMedia("(prefers-color-scheme: light)").matches, - dark: content.matchMedia("(prefers-color-scheme: dark)").matches, - }; - } - ); + let prefersColorScheme = await getPrefersColorSchemeInfo({ win: pbmWindowA }); ok( prefersColorScheme.light && !prefersColorScheme.dark, "Content of dark themed PBM window should still be themed light" @@ -312,3 +337,101 @@ add_task(async function test_theme_switch_updates_existing_pbm_win() { await BrowserTestUtils.closeWindow(windowB); await BrowserTestUtils.closeWindow(pbmWindow); }); + +// pageInfo windows should inherit the PBM window dark theme. +add_task(async function test_pbm_dark_page_info() { + for (let isPBM of [false, true]) { + let win = await BrowserTestUtils.openNewBrowserWindow({ + private: isPBM, + }); + let windowTypeStr = isPBM ? "private" : "normal"; + + info(`Opening pageInfo from ${windowTypeStr} browsing.`); + + await BrowserTestUtils.withNewTab( + { gBrowser: win.gBrowser, url: "https://example.com" }, + async () => { + let pageInfo = win.BrowserPageInfo(null, "securityTab"); + await BrowserTestUtils.waitForEvent(pageInfo, "page-info-init"); + + let prefersColorScheme = await getPrefersColorSchemeInfo({ + win: pageInfo, + chrome: true, + }); + if (isPBM) { + ok( + !prefersColorScheme.light && prefersColorScheme.dark, + "pageInfo from private window should be themed dark." + ); + } else { + ok( + prefersColorScheme.light && !prefersColorScheme.dark, + "pageInfo from normal window should be themed light." + ); + } + + pageInfo.close(); + } + ); + + await BrowserTestUtils.closeWindow(win); + } +}); + +// Prompts should inherit the PBM window dark theme. +add_task(async function test_pbm_dark_prompts() { + const { MODAL_TYPE_TAB, MODAL_TYPE_CONTENT } = Services.prompt; + + for (let isPBM of [false, true]) { + let win = await BrowserTestUtils.openNewBrowserWindow({ + private: isPBM, + }); + + // TODO: Once Bug 1751953 has been fixed, we can also test MODAL_TYPE_WINDOW + // here. + for (let modalType of [MODAL_TYPE_TAB, MODAL_TYPE_CONTENT]) { + let windowTypeStr = isPBM ? "private" : "normal"; + let modalTypeStr = modalType == MODAL_TYPE_TAB ? "tab" : "content"; + + info(`Opening ${modalTypeStr} prompt from ${windowTypeStr} browsing.`); + + let openPromise = PromptTestUtils.waitForPrompt( + win.gBrowser.selectedBrowser, + { + modalType, + promptType: "alert", + } + ); + let promptPromise = Services.prompt.asyncAlert( + win.gBrowser.selectedBrowser.browsingContext, + modalType, + "Hello", + "Hello, world!" + ); + + let dialog = await openPromise; + + let prefersColorScheme = await getPrefersColorSchemeInfo({ + win: dialog.ui.prompt, + chrome: true, + }); + + if (isPBM) { + ok( + !prefersColorScheme.light && prefersColorScheme.dark, + "Prompt from private window should be themed dark." + ); + } else { + ok( + prefersColorScheme.light && !prefersColorScheme.dark, + "Prompt from normal window should be themed light." + ); + } + + await PromptTestUtils.handlePrompt(dialog); + await promptPromise; + } + + await BrowserTestUtils.closeWindow(win); + } +});