mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-02 09:18:36 +02:00
Bug 1968779 - Wait for builtin-newtab.js to signal that it has finished onStartup before allowing ActivityStream to be instantiated. r=pdahiya
Differential Revision: https://phabricator.services.mozilla.com/D251397
This commit is contained in:
parent
4a3b6f3796
commit
0dd415b292
3 changed files with 70 additions and 62 deletions
|
|
@ -464,10 +464,16 @@ class BaseAboutNewTabRedirector {
|
|||
export class AboutNewTabRedirectorParent extends BaseAboutNewTabRedirector {
|
||||
#addonInitialized = false;
|
||||
#suspendedChannels = [];
|
||||
#addonInitializedPromise = null;
|
||||
#addonInitializedResolver = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
let { promise, resolve } = Promise.withResolvers();
|
||||
this.#addonInitializedPromise = promise;
|
||||
this.#addonInitializedResolver = resolve;
|
||||
|
||||
ChromeUtils.registerWindowActor("AboutNewTab", {
|
||||
parent: {
|
||||
esModuleURI: "resource:///actors/AboutNewTabParent.sys.mjs",
|
||||
|
|
@ -499,18 +505,30 @@ export class AboutNewTabRedirectorParent extends BaseAboutNewTabRedirector {
|
|||
* Waits for the AddonManager to be fully initialized, and for the built-in
|
||||
* addon to be ready. Once that's done, it tterates any suspended channels and
|
||||
* resumes them, now that the built-in addon has been set up.
|
||||
*
|
||||
* @returns {Promise<undefined>}
|
||||
* Resolves when the built-in addon has initialized and all suspended
|
||||
* channels are resumed.
|
||||
*/
|
||||
builtInAddonInitialized() {
|
||||
notifyBuiltInAddonInitialized() {
|
||||
this.#addonInitialized = true;
|
||||
|
||||
for (let suspendedChannel of this.#suspendedChannels) {
|
||||
suspendedChannel.resume();
|
||||
}
|
||||
this.#suspendedChannels = [];
|
||||
this.#addonInitializedResolver();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Promise that reoslves when the newtab built-in addon has notified
|
||||
* that it has finished initializing. If this is somehow checked when
|
||||
* BROWSER_NEWTAB_AS_ADDON is not true, then this always resolves.
|
||||
*
|
||||
* @type {Promise<undefined>}
|
||||
*/
|
||||
get promiseBuiltInAddonInitialized() {
|
||||
if (!AppConstants.BROWSER_NEWTAB_AS_ADDON) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this.#addonInitializedPromise;
|
||||
}
|
||||
|
||||
newChannel(uri, loadInfo) {
|
||||
|
|
|
|||
|
|
@ -48,45 +48,51 @@ this.builtin_newtab = class extends ExtensionAPI {
|
|||
return;
|
||||
}
|
||||
|
||||
const { rootURI } = this.extension;
|
||||
try {
|
||||
const { rootURI } = this.extension;
|
||||
|
||||
resProto.setSubstitutionWithFlags(
|
||||
ResourceSubstitution,
|
||||
rootURI,
|
||||
Ci.nsISubstitutingProtocolHandler.ALLOW_CONTENT_ACCESS
|
||||
);
|
||||
|
||||
let aomStartup = Cc[
|
||||
"@mozilla.org/addons/addon-manager-startup;1"
|
||||
].getService(Ci.amIAddonManagerStartup);
|
||||
const manifestURI = Services.io.newURI(
|
||||
"manifest.json",
|
||||
null,
|
||||
this.extension.rootURI
|
||||
);
|
||||
this.#chromeHandle = aomStartup.registerChrome(manifestURI, [
|
||||
["content", "newtab", "data/content", "contentaccessible=yes"],
|
||||
]);
|
||||
|
||||
let redirector = Cc[
|
||||
"@mozilla.org/network/protocol/about;1?what=newtab"
|
||||
].getService(Ci.nsIAboutModule).wrappedJSObject;
|
||||
|
||||
if (this.extension.rootURI.spec.endsWith("newtab@mozilla.org.xpi!/")) {
|
||||
// We must be a train-hopped XPI running in this app. This means we
|
||||
// may have Fluent files or Glean pings/metrics to register dynamically.
|
||||
const newtabFileSource = new L10nFileSource(
|
||||
"newtab",
|
||||
"app",
|
||||
SUPPORTED_LOCALES,
|
||||
`resource://newtab/locales/{locale}/`
|
||||
resProto.setSubstitutionWithFlags(
|
||||
ResourceSubstitution,
|
||||
rootURI,
|
||||
Ci.nsISubstitutingProtocolHandler.ALLOW_CONTENT_ACCESS
|
||||
);
|
||||
L10nRegistry.getInstance().registerSources([newtabFileSource]);
|
||||
|
||||
// Dynamically register any Glean pings/metrics here.
|
||||
this.registerMetricsFromJson();
|
||||
let aomStartup = Cc[
|
||||
"@mozilla.org/addons/addon-manager-startup;1"
|
||||
].getService(Ci.amIAddonManagerStartup);
|
||||
const manifestURI = Services.io.newURI(
|
||||
"manifest.json",
|
||||
null,
|
||||
this.extension.rootURI
|
||||
);
|
||||
this.#chromeHandle = aomStartup.registerChrome(manifestURI, [
|
||||
["content", "newtab", "data/content", "contentaccessible=yes"],
|
||||
]);
|
||||
|
||||
let redirector = Cc[
|
||||
"@mozilla.org/network/protocol/about;1?what=newtab"
|
||||
].getService(Ci.nsIAboutModule).wrappedJSObject;
|
||||
|
||||
if (this.extension.rootURI.spec.endsWith("newtab@mozilla.org.xpi!/")) {
|
||||
// We must be a train-hopped XPI running in this app. This means we
|
||||
// may have Fluent files or Glean pings/metrics to register dynamically.
|
||||
const newtabFileSource = new L10nFileSource(
|
||||
"newtab",
|
||||
"app",
|
||||
SUPPORTED_LOCALES,
|
||||
`resource://newtab/locales/{locale}/`
|
||||
);
|
||||
L10nRegistry.getInstance().registerSources([newtabFileSource]);
|
||||
|
||||
// Dynamically register any Glean pings/metrics here.
|
||||
this.registerMetricsFromJson();
|
||||
}
|
||||
redirector.notifyBuiltInAddonInitialized();
|
||||
Glean.newtab.addonReadySuccess.set(true);
|
||||
} catch(e) {
|
||||
Glean.newtab.addonReadySuccess.set(false);
|
||||
throw e;
|
||||
}
|
||||
redirector.builtInAddonInitialized();
|
||||
}
|
||||
|
||||
onShutdown() {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ const lazy = {};
|
|||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
ActivityStream: "resource://newtab/lib/ActivityStream.sys.mjs",
|
||||
AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
|
||||
AddonManagerPrivate: "resource://gre/modules/AddonManager.sys.mjs",
|
||||
ObjectUtils: "resource://gre/modules/ObjectUtils.sys.mjs",
|
||||
});
|
||||
|
||||
|
|
@ -160,28 +159,13 @@ export const AboutNewTab = {
|
|||
}
|
||||
|
||||
if (AppConstants.BROWSER_NEWTAB_AS_ADDON) {
|
||||
let addonPolicy = WebExtensionPolicy.getByID(BUILTIN_ADDON_ID);
|
||||
if (!addonPolicy) {
|
||||
// If this is the first time that the build flag was set to true, we
|
||||
// might not yet have refreshed the addon database cache yet, in which
|
||||
// case the addonPolicy will be null. In that case, we'll wait for the
|
||||
// database to be ready before proceeding.
|
||||
//
|
||||
// We don't always just wait for the databaseReady Promise to resolve
|
||||
// in order to avoid regressing newtab render times by needlessly
|
||||
// going back to the event loop.
|
||||
await lazy.AddonManagerPrivate.databaseReady;
|
||||
addonPolicy = WebExtensionPolicy.getByID(BUILTIN_ADDON_ID);
|
||||
}
|
||||
// Wait until the built-in addon has reported that it has finished
|
||||
// initializing.
|
||||
let redirector = Cc[
|
||||
"@mozilla.org/network/protocol/about;1?what=newtab"
|
||||
].getService(Ci.nsIAboutModule).wrappedJSObject;
|
||||
|
||||
if (!addonPolicy) {
|
||||
// Something's gone very wrong here, and we should collect telemetry
|
||||
// about it.
|
||||
Glean.newtab.addonReadySuccess.set(false);
|
||||
} else {
|
||||
await addonPolicy.readyPromise;
|
||||
Glean.newtab.addonReadySuccess.set(true);
|
||||
}
|
||||
await redirector.promiseBuiltInAddonInitialized;
|
||||
} else {
|
||||
// We may have had the built-in addon installed in the past. Since the
|
||||
// flag is false, let's go ahead and remove it. We don't need to await on
|
||||
|
|
|
|||
Loading…
Reference in a new issue