Bug 1897508 - Separate out search engine icon updates into a separate notification subject. r=search-reviewers,settings-reviewers,mcheang

This also avoids sending an engine-update Glean event for the default engine by not handling the engine-icon-update
notification in the update tracking code.

Differential Revision: https://phabricator.services.mozilla.com/D210838
This commit is contained in:
Mark Banner 2024-05-24 09:10:05 +00:00
parent 0600e5f0d8
commit 67039cecb0
10 changed files with 41 additions and 21 deletions

View file

@ -30,7 +30,7 @@ async function promiseEngineIconLoaded(engineName) {
"browser-search-engine-modified", "browser-search-engine-modified",
(engine, verb) => { (engine, verb) => {
engine.QueryInterface(Ci.nsISearchEngine); engine.QueryInterface(Ci.nsISearchEngine);
return verb == "engine-changed" && engine.name == engineName; return verb == "engine-icon-changed" && engine.name == engineName;
} }
); );
Assert.ok( Assert.ok(

View file

@ -749,6 +749,7 @@ class EngineStore {
this.notifyRowCountChanged(gEngineView.lastEngineIndex, 1); this.notifyRowCountChanged(gEngineView.lastEngineIndex, 1);
break; break;
case "engine-changed": case "engine-changed":
case "engine-icon-changed":
this.updateEngine(engine); this.updateEngine(engine);
this.notifyRebuildViews(); this.notifyRebuildViews();
break; break;

View file

@ -131,6 +131,10 @@ class SearchUtils {
/** /**
* Gets the engine with a given alias. * Gets the engine with a given alias.
* *
* Note: engines returned from this list may be updated at any time. If you
* are caching the icon or other fields for more than a single engagement of
* the urlbar, consider observing the SEARCH_ENGINE_TOPIC.
*
* @param {string} alias * @param {string} alias
* A search engine alias. The alias string comparison is case insensitive. * A search engine alias. The alias string comparison is case insensitive.
* @param {string} [searchString] * @param {string} [searchString]

View file

@ -453,7 +453,10 @@ export class AppProvidedSearchEngine extends SearchEngine {
this.#blobURLPromise = null; this.#blobURLPromise = null;
} }
this.#blobURLPromise = Promise.resolve(blobURL); this.#blobURLPromise = Promise.resolve(blobURL);
lazy.SearchUtils.notifyAction(this, lazy.SearchUtils.MODIFIED_TYPE.CHANGED); lazy.SearchUtils.notifyAction(
this,
lazy.SearchUtils.MODIFIED_TYPE.ICON_CHANGED
);
} }
/** /**

View file

@ -798,7 +798,7 @@ export class SearchEngine {
if (this._engineAddedToStore) { if (this._engineAddedToStore) {
lazy.SearchUtils.notifyAction( lazy.SearchUtils.notifyAction(
this, this,
lazy.SearchUtils.MODIFIED_TYPE.CHANGED lazy.SearchUtils.MODIFIED_TYPE.ICON_CHANGED
); );
} }
this._hasPreferredIcon = isPreferred; this._hasPreferredIcon = isPreferred;

View file

@ -5,6 +5,8 @@
const lazy = {}; const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, { ChromeUtils.defineESModuleGetters(lazy, {
AppProvidedSearchEngine:
"resource://gre/modules/AppProvidedSearchEngine.sys.mjs",
DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs", DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs",
ObjectUtils: "resource://gre/modules/ObjectUtils.sys.mjs", ObjectUtils: "resource://gre/modules/ObjectUtils.sys.mjs",
SearchUtils: "resource://gre/modules/SearchUtils.sys.mjs", SearchUtils: "resource://gre/modules/SearchUtils.sys.mjs",
@ -501,6 +503,15 @@ export class SearchSettings {
case lazy.SearchUtils.MODIFIED_TYPE.REMOVED: case lazy.SearchUtils.MODIFIED_TYPE.REMOVED:
this._delayedWrite(); this._delayedWrite();
break; break;
case lazy.SearchUtils.MODIFIED_TYPE.ICON_CHANGED:
// Application Provided Search Engines have their icons stored in
// Remote Settings, so we don't need to update the saved settings.
if (
!(engine?.wrappedJSObject instanceof lazy.AppProvidedSearchEngine)
) {
this._delayedWrite();
}
break;
} }
break; break;
case lazy.SearchUtils.TOPIC_SEARCH_SERVICE: case lazy.SearchUtils.TOPIC_SEARCH_SERVICE:

View file

@ -186,6 +186,7 @@ export var SearchUtils = {
TOPIC_ENGINE_MODIFIED: "browser-search-engine-modified", TOPIC_ENGINE_MODIFIED: "browser-search-engine-modified",
MODIFIED_TYPE: { MODIFIED_TYPE: {
CHANGED: "engine-changed", CHANGED: "engine-changed",
ICON_CHANGED: "engine-icon-changed",
REMOVED: "engine-removed", REMOVED: "engine-removed",
ADDED: "engine-added", ADDED: "engine-added",
DEFAULT: "engine-default", DEFAULT: "engine-default",

View file

@ -234,8 +234,8 @@ add_task(async function test_icon_added_existing_engine() {
}); });
await client.db.update(mock.record, Date.now()); await client.db.update(mock.record, Date.now());
let promiseEngineUpdated = SearchTestUtils.promiseSearchNotification( let promiseIconChanged = SearchTestUtils.promiseSearchNotification(
SearchUtils.MODIFIED_TYPE.CHANGED, SearchUtils.MODIFIED_TYPE.ICON_CHANGED,
SearchUtils.TOPIC_ENGINE_MODIFIED SearchUtils.TOPIC_ENGINE_MODIFIED
); );
@ -250,7 +250,7 @@ add_task(async function test_icon_added_existing_engine() {
SearchTestUtils.idleService._fireObservers("idle"); SearchTestUtils.idleService._fireObservers("idle");
await promiseEngineUpdated; await promiseIconChanged;
await assertEngineIcon("engine_no_initial_icon name", "bigIcon.ico"); await assertEngineIcon("engine_no_initial_icon name", "bigIcon.ico");
}); });
@ -270,8 +270,8 @@ add_task(async function test_icon_updated() {
}); });
await client.db.update(mock.record, Date.now()); await client.db.update(mock.record, Date.now());
let promiseEngineUpdated = SearchTestUtils.promiseSearchNotification( let promiseIconChanged = SearchTestUtils.promiseSearchNotification(
SearchUtils.MODIFIED_TYPE.CHANGED, SearchUtils.MODIFIED_TYPE.ICON_CHANGED,
SearchUtils.TOPIC_ENGINE_MODIFIED SearchUtils.TOPIC_ENGINE_MODIFIED
); );
@ -285,7 +285,7 @@ add_task(async function test_icon_updated() {
}); });
SearchTestUtils.idleService._fireObservers("idle"); SearchTestUtils.idleService._fireObservers("idle");
await promiseEngineUpdated; await promiseIconChanged;
await assertEngineIcon("engine_icon_updates name", "bigIcon.ico"); await assertEngineIcon("engine_icon_updates name", "bigIcon.ico");
}); });
@ -296,12 +296,12 @@ add_task(async function test_icon_not_local() {
await assertEngineIcon("engine_icon_not_local name", null); await assertEngineIcon("engine_icon_not_local name", null);
// A download should have been queued, so fire idle to trigger it. // A download should have been queued, so fire idle to trigger it.
let promiseEngineUpdated = SearchTestUtils.promiseSearchNotification( let promiseIconChanged = SearchTestUtils.promiseSearchNotification(
SearchUtils.MODIFIED_TYPE.CHANGED, SearchUtils.MODIFIED_TYPE.ICON_CHANGED,
SearchUtils.TOPIC_ENGINE_MODIFIED SearchUtils.TOPIC_ENGINE_MODIFIED
); );
SearchTestUtils.idleService._fireObservers("idle"); SearchTestUtils.idleService._fireObservers("idle");
await promiseEngineUpdated; await promiseIconChanged;
await assertEngineIcon("engine_icon_not_local name", "bigIcon.ico"); await assertEngineIcon("engine_icon_not_local name", "bigIcon.ico");
}); });
@ -313,12 +313,12 @@ add_task(async function test_icon_out_of_date() {
await assertEngineIcon("engine_icon_out_of_date name", "remoteIcon.ico"); await assertEngineIcon("engine_icon_out_of_date name", "remoteIcon.ico");
// A download should have been queued, so fire idle to trigger it. // A download should have been queued, so fire idle to trigger it.
let promiseEngineUpdated = SearchTestUtils.promiseSearchNotification( let promiseIconChanged = SearchTestUtils.promiseSearchNotification(
SearchUtils.MODIFIED_TYPE.CHANGED, SearchUtils.MODIFIED_TYPE.ICON_CHANGED,
SearchUtils.TOPIC_ENGINE_MODIFIED SearchUtils.TOPIC_ENGINE_MODIFIED
); );
SearchTestUtils.idleService._fireObservers("idle"); SearchTestUtils.idleService._fireObservers("idle");
await promiseEngineUpdated; await promiseIconChanged;
await assertEngineIcon("engine_icon_out_of_date name", "bigIcon.ico"); await assertEngineIcon("engine_icon_out_of_date name", "bigIcon.ico");
}); });

View file

@ -36,8 +36,8 @@ add_task(async function test_icon_types() {
SearchUtils.MODIFIED_TYPE.ADDED, SearchUtils.MODIFIED_TYPE.ADDED,
SearchUtils.TOPIC_ENGINE_MODIFIED SearchUtils.TOPIC_ENGINE_MODIFIED
); );
let promiseEngineChanged = SearchTestUtils.promiseSearchNotification( let promiseIconChanged = SearchTestUtils.promiseSearchNotification(
SearchUtils.MODIFIED_TYPE.CHANGED, SearchUtils.MODIFIED_TYPE.ICON_CHANGED,
SearchUtils.TOPIC_ENGINE_MODIFIED SearchUtils.TOPIC_ENGINE_MODIFIED
); );
const engineData = { const engineData = {
@ -54,7 +54,7 @@ add_task(async function test_icon_types() {
let engine = await promiseEngineAdded; let engine = await promiseEngineAdded;
// Ensure this is a nsISearchEngine. // Ensure this is a nsISearchEngine.
engine.QueryInterface(Ci.nsISearchEngine); engine.QueryInterface(Ci.nsISearchEngine);
await promiseEngineChanged; await promiseIconChanged;
Assert.ok(await engine.getIconURL(), `${test.name} engine has an icon`); Assert.ok(await engine.getIconURL(), `${test.name} engine has an icon`);
Assert.ok( Assert.ok(

View file

@ -201,8 +201,8 @@ add_task(async function test_load_favicon_invalid_redirect() {
}); });
add_task(async function test_load_favicon_redirect() { add_task(async function test_load_favicon_redirect() {
let promiseEngineChanged = SearchTestUtils.promiseSearchNotification( let promiseIconChanged = SearchTestUtils.promiseSearchNotification(
SearchUtils.MODIFIED_TYPE.CHANGED, SearchUtils.MODIFIED_TYPE.ICON_CHANGED,
SearchUtils.TOPIC_ENGINE_MODIFIED SearchUtils.TOPIC_ENGINE_MODIFIED
); );
@ -216,7 +216,7 @@ add_task(async function test_load_favicon_redirect() {
let engine = await Services.search.getEngineByName("Example"); let engine = await Services.search.getEngineByName("Example");
await promiseEngineChanged; await promiseIconChanged;
Assert.ok(await engine.getIconURL(), "Should have set an iconURI"); Assert.ok(await engine.getIconURL(), "Should have set an iconURI");
Assert.ok( Assert.ok(