Skip to content

Commit e07e9b4

Browse files
committed
Bug 1946569 - Part 3: Suspend all about:newtab or about:home channels until the built-in addon is ready. r=thecount,pdahiya,home-newtab-reviewers,willdurand
Differential Revision: https://phabricator.services.mozilla.com/D237642
1 parent 87ebe80 commit e07e9b4

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

browser/components/newtab/AboutNewTabRedirector.sys.mjs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
2929
const lazy = {};
3030

3131
ChromeUtils.defineESModuleGetters(lazy, {
32+
AddonManagerPrivate: "resource://gre/modules/AddonManager.sys.mjs",
3233
BasePromiseWorker: "resource://gre/modules/PromiseWorker.sys.mjs",
3334
});
3435

@@ -60,6 +61,8 @@ const PREF_SEPARATE_PRIVILEGEDABOUT_CONTENT_PROCESS =
6061
"browser.tabs.remote.separatePrivilegedContentProcess";
6162
const PREF_ACTIVITY_STREAM_DEBUG = "browser.newtabpage.activity-stream.debug";
6263

64+
const BUILTIN_ADDON_ID = "newtab@mozilla.org";
65+
6366
/**
6467
* The AboutHomeStartupCacheChild is responsible for connecting the
6568
* AboutNewTabRedirectorChild with a cached document and script for about:home
@@ -462,6 +465,9 @@ class BaseAboutNewTabRedirector {
462465
* before the AboutNewTabRedirectorChild has a chance to handle the request).
463466
*/
464467
export class AboutNewTabRedirectorParent extends BaseAboutNewTabRedirector {
468+
#addonInitialized = false;
469+
#suspendedChannels = [];
470+
465471
constructor() {
466472
super();
467473

@@ -489,6 +495,36 @@ export class AboutNewTabRedirectorParent extends BaseAboutNewTabRedirector {
489495
matches: ["about:home*", "about:newtab*"],
490496
remoteTypes: ["privilegedabout"],
491497
});
498+
499+
if (AppConstants.BROWSER_NEWTAB_AS_ADDON) {
500+
this.#waitForBuiltInAddonInitialized();
501+
}
502+
}
503+
504+
/**
505+
* Waits for the AddonManager to be fully initialized, and for the built-in
506+
* addon to be ready. Once that's done, it tterates any suspended channels and
507+
* resumes them, now that the built-in addon has been set up.
508+
*
509+
* @returns {Promise<undefined>}
510+
* Resolves when the built-in addon has initialized and all suspended
511+
* channels are resumed.
512+
*/
513+
async #waitForBuiltInAddonInitialized() {
514+
let addon = WebExtensionPolicy.getByID(BUILTIN_ADDON_ID);
515+
if (!addon?.readyPromise) {
516+
await lazy.AddonManagerPrivate.databaseReady;
517+
addon = WebExtensionPolicy.getByID(BUILTIN_ADDON_ID);
518+
}
519+
520+
await addon.readyPromise;
521+
522+
this.#addonInitialized = true;
523+
524+
for (let suspendedChannel of this.#suspendedChannels) {
525+
suspendedChannel.resume();
526+
}
527+
this.#suspendedChannels = [];
492528
}
493529

494530
newChannel(uri, loadInfo) {
@@ -506,8 +542,31 @@ export class AboutNewTabRedirectorParent extends BaseAboutNewTabRedirector {
506542
loadInfo
507543
);
508544
resultChannel.originalURI = uri;
545+
546+
if (AppConstants.BROWSER_NEWTAB_AS_ADDON && !this.#addonInitialized) {
547+
return this.#getSuspendedChannel(resultChannel);
548+
}
549+
509550
return resultChannel;
510551
}
552+
553+
/**
554+
* Wraps an nsIChannel with an nsISuspendableChannelWrapper, suspends that
555+
* wrapper, and then stores the wrapper in #suspendedChannels so that it can
556+
* be resumed with a call to #notifyBuildInAddonInitialized.
557+
*
558+
* @param {nsIChannel} innerChannel
559+
* The channel to wrap and suspend.
560+
* @returns {nsISuspendableChannelWrapper}
561+
*/
562+
#getSuspendedChannel(innerChannel) {
563+
let suspendedChannel =
564+
Services.io.newSuspendableChannelWrapper(innerChannel);
565+
suspendedChannel.suspend();
566+
567+
this.#suspendedChannels.push(suspendedChannel);
568+
return suspendedChannel;
569+
}
511570
}
512571

513572
/**

0 commit comments

Comments
 (0)