commit 05874864bfe4325ec857ade6b539f152c2fa5bd1
parent bf17dfb09e817999a6e99bc251b71dbdc709d8d9
Author: Mike Conley <mconley@mozilla.com>
Date: Fri, 24 Oct 2025 20:10:59 +0000
Bug 1996324 - Part 2: Add the newtab addon version to about:home startup cache metadata, and check it on initialization. r=home-newtab-reviewers,thecount
Differential Revision: https://phabricator.services.mozilla.com/D270039
Diffstat:
3 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/browser/components/newtab/AboutHomeStartupCache.sys.mjs b/browser/components/newtab/AboutHomeStartupCache.sys.mjs
@@ -5,6 +5,8 @@
let lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
+ AboutNewTabResourceMapping:
+ "resource:///modules/AboutNewTabResourceMapping.sys.mjs",
AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs",
E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs",
@@ -37,6 +39,10 @@ export var AboutHomeStartupCache = {
// The version is currently set to the build ID, meaning that the cache
// is invalidated after every upgrade (like the main startup cache).
CACHE_VERSION_META_KEY: "version",
+ // Similar, with newtab now able to update out-of-band from the rest of the
+ // application, it's possible that the newtab version has changed since the
+ // cache was written. If so, we should ignore the cache.
+ CACHE_NEWTAB_VERSION_META_KEY: "newtab-version",
LOG_NAME: "AboutHomeStartupCache",
@@ -458,7 +464,9 @@ export var AboutHomeStartupCache = {
);
} catch (e) {
if (e.result == Cr.NS_ERROR_NOT_AVAILABLE) {
- this.log.debug("Cache meta data does not exist. Closing streams.");
+ this.log.debug(
+ "Cache meta data for version does not exist. Closing streams."
+ );
this.pagePipe.outputStream.close();
this.scriptPipe.outputStream.close();
this.setDeferredResult(this.CACHE_RESULT_SCALARS.DOES_NOT_EXIST);
@@ -471,7 +479,38 @@ export var AboutHomeStartupCache = {
this.log.info("Version retrieved is", version);
if (version != Services.appinfo.appBuildID) {
- this.log.info("Version does not match! Dooming and closing streams.\n");
+ this.log.info("Version does not match! Dooming and closing streams.");
+ // This cache is no good - doom it, and prepare for a new one.
+ this.clearCache();
+ this.pagePipe.outputStream.close();
+ this.scriptPipe.outputStream.close();
+ this.setDeferredResult(this.CACHE_RESULT_SCALARS.INVALIDATED);
+ return;
+ }
+
+ let newtabVersion;
+ try {
+ newtabVersion = this._cacheEntry.getMetaDataElement(
+ this.CACHE_NEWTAB_VERSION_META_KEY
+ );
+ } catch (e) {
+ if (e.result == Cr.NS_ERROR_NOT_AVAILABLE) {
+ this.log.debug(
+ "Cache meta data for newtab version does not exist. Closing streams."
+ );
+ this.pagePipe.outputStream.close();
+ this.scriptPipe.outputStream.close();
+ this.setDeferredResult(this.CACHE_RESULT_SCALARS.DOES_NOT_EXIST);
+ return;
+ }
+
+ throw e;
+ }
+
+ if (newtabVersion != lazy.AboutNewTabResourceMapping.addonVersion) {
+ this.log.info(
+ "New Tab version does not match! Dooming and closing streams."
+ );
// This cache is no good - doom it, and prepare for a new one.
this.clearCache();
this.pagePipe.outputStream.close();
@@ -607,7 +646,7 @@ export var AboutHomeStartupCache = {
);
try {
this._cacheEntry.setMetaDataElement(
- "version",
+ this.CACHE_VERSION_META_KEY,
Services.appinfo.appBuildID
);
} catch (e) {
@@ -615,6 +654,16 @@ export var AboutHomeStartupCache = {
reject(e);
return;
}
+ try {
+ this._cacheEntry.setMetaDataElement(
+ this.CACHE_NEWTAB_VERSION_META_KEY,
+ lazy.AboutNewTabResourceMapping.addonVersion
+ );
+ } catch (e) {
+ this.log.error("Failed to write newtab version.");
+ reject(e);
+ return;
+ }
this.log.trace(`Version is set to ${Services.appinfo.appBuildID}.`);
this.log.info("Caching of page and script is done.");
resolve();
diff --git a/browser/components/newtab/test/browser/abouthomecache/browser.toml b/browser/components/newtab/test/browser/abouthomecache/browser.toml
@@ -23,6 +23,8 @@ prefs = [
["browser_basic_endtoend.js"]
+["browser_bump_newtab_version.js"]
+
["browser_bump_version.js"]
["browser_clearCacheAndUninit.js"]
diff --git a/browser/components/newtab/test/browser/abouthomecache/browser_bump_newtab_version.js b/browser/components/newtab/test/browser/abouthomecache/browser_bump_newtab_version.js
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+ https://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { AboutNewTabResourceMapping } = ChromeUtils.importESModule(
+ "resource:///modules/AboutNewTabResourceMapping.sys.mjs"
+);
+
+/**
+ * Test that if the "newtab-version" metadata on the cache entry doesn't match
+ * the expectation that we ignore the cache and load the dynamic about:home
+ * document.
+ */
+add_task(async function test_newtab_bump_version() {
+ await withFullyLoadedAboutHome(async browser => {
+ // First, ensure that a pre-existing cache exists.
+ await simulateRestart(browser);
+
+ let cacheEntry = await AboutHomeStartupCache.ensureCacheEntry();
+ Assert.equal(
+ cacheEntry.getMetaDataElement("newtab-version"),
+ AboutNewTabResourceMapping.addonVersion,
+ "Cache entry should be versioned on the newtab version"
+ );
+ cacheEntry.setMetaDataElement("newtab-version", "somethingnew");
+ // We don't need to shutdown write or ensure the cache wins the race,
+ // since we expect the cache to be blown away because the version number
+ // has been bumped.
+ await simulateRestart(browser, {
+ withAutoShutdownWrite: false,
+ ensureCacheWinsRace: false,
+ });
+ await ensureDynamicAboutHome(
+ browser,
+ AboutHomeStartupCache.CACHE_RESULT_SCALARS.INVALIDATED
+ );
+ });
+});