Skip to content

Commit 8c1f5ef

Browse files
committed
Bug 1973269 - Pass the URI directly to browser chrome page r=asuth,Gijs
Currently we load the URI using the resulting BrowsingContext, but that causes race with session restore. Passing the URI as an argument to the browser chrome page solves the issue. Differential Revision: https://phabricator.services.mozilla.com/D254539
1 parent a82a493 commit 8c1f5ef

File tree

2 files changed

+71
-30
lines changed

2 files changed

+71
-30
lines changed

dom/clients/manager/ClientOpenWindowUtils.cpp

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,16 @@ static Result<Ok, nsresult> OpenNewWindow(
215215
nsOpenWindowInfo* aOpenWindowInfo) {
216216
nsresult rv;
217217

218+
// XXX(krosylight): In an ideal world we should be able to pass the nsIURI
219+
// directly. See bug 1485961.
220+
nsAutoCString uriToLoad;
221+
MOZ_TRY(aArgsValidated.uri->GetSpec(uriToLoad));
222+
223+
nsCOMPtr<nsISupportsCString> nsUriToLoad =
224+
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
225+
MOZ_TRY(rv);
226+
MOZ_TRY(nsUriToLoad->SetData(uriToLoad));
227+
218228
nsCOMPtr<nsISupportsPRBool> nsFalse =
219229
do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID, &rv);
220230
MOZ_TRY(rv);
@@ -227,7 +237,7 @@ static Result<Ok, nsresult> OpenNewWindow(
227237

228238
nsCOMPtr<nsIMutableArray> args = do_CreateInstance(NS_ARRAY_CONTRACTID);
229239
// https://searchfox.org/mozilla-central/rev/02d33f4bf984f65bd394bfd2d19d66569ae2cfe1/browser/base/content/browser-init.js#725-735
230-
args->AppendElement(nullptr); // 0: uriToLoad
240+
args->AppendElement(nsUriToLoad); // 0: uriToLoad
231241
args->AppendElement(nullptr); // 1: extraOptions
232242
args->AppendElement(nullptr); // 2: referrerInfo
233243
args->AppendElement(nullptr); // 3: postData
@@ -310,7 +320,7 @@ void OpenWindow(const ClientOpenWindowArgsParsed& aArgsValidated,
310320

311321
void WaitForLoad(const ClientOpenWindowArgsParsed& aArgsValidated,
312322
BrowsingContext* aBrowsingContext,
313-
ClientOpPromise::Private* aPromise) {
323+
ClientOpPromise::Private* aPromise, bool aShouldLoadURI) {
314324
MOZ_DIAGNOSTIC_ASSERT(aBrowsingContext);
315325

316326
RefPtr<ClientOpPromise::Private> promise = aPromise;
@@ -328,7 +338,7 @@ void WaitForLoad(const ClientOpenWindowArgsParsed& aArgsValidated,
328338
return;
329339
}
330340

331-
// Add a progress listener before we start the load of the service worker URI
341+
// Add a progress listener before we start the load of the requested URI
332342
RefPtr<WebProgressListener> listener = new WebProgressListener(
333343
aBrowsingContext, aArgsValidated.baseURI, do_AddRef(promise));
334344

@@ -342,24 +352,27 @@ void WaitForLoad(const ClientOpenWindowArgsParsed& aArgsValidated,
342352
return;
343353
}
344354

345-
// Load the service worker URI
346-
RefPtr<nsDocShellLoadState> loadState =
347-
new nsDocShellLoadState(aArgsValidated.uri);
348-
loadState->SetTriggeringPrincipal(aArgsValidated.principal);
349-
loadState->SetFirstParty(true);
350-
loadState->SetLoadFlags(
351-
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL);
352-
loadState->SetTriggeringRemoteType(
353-
aArgsValidated.originContent
354-
? aArgsValidated.originContent->GetRemoteType()
355-
: NOT_REMOTE_TYPE);
356-
357-
rv = aBrowsingContext->LoadURI(loadState, true);
358-
if (NS_FAILED(rv)) {
359-
CopyableErrorResult result;
360-
result.ThrowInvalidStateError("Unable to start the load of the actual URI");
361-
promise->Reject(result, __func__);
362-
return;
355+
if (aShouldLoadURI) {
356+
// Load the requested URI
357+
RefPtr<nsDocShellLoadState> loadState =
358+
new nsDocShellLoadState(aArgsValidated.uri);
359+
loadState->SetTriggeringPrincipal(aArgsValidated.principal);
360+
loadState->SetFirstParty(true);
361+
loadState->SetLoadFlags(
362+
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL);
363+
loadState->SetTriggeringRemoteType(
364+
aArgsValidated.originContent
365+
? aArgsValidated.originContent->GetRemoteType()
366+
: NOT_REMOTE_TYPE);
367+
368+
rv = aBrowsingContext->LoadURI(loadState, true);
369+
if (NS_FAILED(rv)) {
370+
CopyableErrorResult result;
371+
result.ThrowInvalidStateError(
372+
"Unable to start the load of the actual URI");
373+
promise->Reject(result, __func__);
374+
return;
375+
}
363376
}
364377

365378
// Hold the listener alive until the promise settles.
@@ -371,8 +384,7 @@ void WaitForLoad(const ClientOpenWindowArgsParsed& aArgsValidated,
371384

372385
#ifdef MOZ_GECKOVIEW
373386
void GeckoViewOpenWindow(const ClientOpenWindowArgsParsed& aArgsValidated,
374-
nsOpenWindowInfo* aOpenInfo, BrowsingContext** aBC,
375-
ErrorResult& aRv) {
387+
nsOpenWindowInfo* aOpenInfo, ErrorResult& aRv) {
376388
MOZ_ASSERT(aOpenInfo);
377389

378390
// passes the request to open a new window to GeckoView. Allowing the
@@ -487,11 +499,13 @@ RefPtr<ClientOpPromise> ClientOpenWindow(
487499

488500
RefPtr<BrowsingContext> bc;
489501
IgnoredErrorResult errResult;
502+
bool shouldLoadURI = true;
490503
#ifdef MOZ_GECKOVIEW
491504
// GeckoView has a delegation for service worker window.
492-
GeckoViewOpenWindow(argsValidated, openInfo, getter_AddRefs(bc), errResult);
505+
GeckoViewOpenWindow(argsValidated, openInfo, errResult);
493506
#else
494507
OpenWindow(argsValidated, openInfo, getter_AddRefs(bc), errResult);
508+
shouldLoadURI = !!bc;
495509
#endif
496510
if (NS_WARN_IF(errResult.Failed())) {
497511
promise->Reject(errResult, __func__);
@@ -500,8 +514,9 @@ RefPtr<ClientOpPromise> ClientOpenWindow(
500514

501515
browsingContextReadyPromise->Then(
502516
GetCurrentSerialEventTarget(), __func__,
503-
[argsValidated, promise](const RefPtr<BrowsingContext>& aBC) {
504-
WaitForLoad(argsValidated, aBC, promise);
517+
[argsValidated, promise,
518+
shouldLoadURI](const RefPtr<BrowsingContext>& aBC) {
519+
WaitForLoad(argsValidated, aBC, promise, shouldLoadURI);
505520
},
506521
[promise]() {
507522
// in case of failure, reject the original promise

dom/notification/test/browser/browser_openwindow_without_window.js

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,31 @@ add_setup(() => {
4646
BrowserTestUtils.concealWindow(window, { signal });
4747
});
4848

49-
for (let permanentPbm of [false, true]) {
49+
let configs = [
50+
{
51+
permanentPbm: false,
52+
browserStartup: 1,
53+
},
54+
{
55+
permanentPbm: true,
56+
browserStartup: 1,
57+
},
58+
{
59+
permanentPbm: false,
60+
browserStartup: 3,
61+
},
62+
];
63+
64+
for (let { permanentPbm, browserStartup } of configs) {
5065
add_task(async function () {
5166
info(`Test with PBM: ${permanentPbm}`);
67+
info(`Test with startup behavior: ${browserStartup}`);
5268

5369
await SpecialPowers.pushPrefEnv({
54-
set: [["browser.privatebrowsing.autostart", permanentPbm]],
70+
set: [
71+
["browser.privatebrowsing.autostart", permanentPbm],
72+
["browser.startup.page", browserStartup],
73+
],
5574
});
5675

5776
let win = await BrowserTestUtils.openNewBrowserWindow();
@@ -85,8 +104,15 @@ for (let permanentPbm of [false, true]) {
85104

86105
registerCleanupFunction(() => SpecialPowers.removeAllServiceWorkerData());
87106

88-
// Now close the current window
89-
await BrowserTestUtils.closeWindow(win);
107+
// Now close the current window via BrowserCommands
108+
// (simple .close() will not trigger session store as it does not notify
109+
// browser-lastwindow-close-granted)
110+
let closedPromise = BrowserTestUtils.windowClosed(win);
111+
win.BrowserCommands.tryToCloseWindow();
112+
await closedPromise;
113+
114+
// Let session startup read the changed pref again
115+
SessionStartup.resetForTest();
90116

91117
let newWinPromise = BrowserTestUtils.waitForNewWindow({
92118
url: OPEN_URI,

0 commit comments

Comments
 (0)