Bug 1747973 - Cache the top-sites query context like we cache other contexts. r=harry
commit996a2cafe472e9934b8cb91db63050f96d8a59cb
authorDrew Willcoxon <adw@mozilla.com>
Mon, 3 Jan 2022 19:18:54 +0000 (3 19:18 +0000)
committerDrew Willcoxon <adw@mozilla.com>
Mon, 3 Jan 2022 19:18:54 +0000 (3 19:18 +0000)
treef8c591d13bb963a0e742c3c544f53f5db7032c23
parent95b8777131fabe6c07b0e9d687f7f1a1a296e52b
Bug 1747973 - Cache the top-sites query context like we cache other contexts. r=harry

This caches the top-sites context like we cache other contexts. The cache is
cleared when the top sites change or are enabled/disabled.

Unlike other contexts, which are evicted from the cache once too many newer
contexts are cached, the top-sites context is never evicted due to space reasons
because showing the top sites is a frequent action.

I wanted to keep the logic around when/whether the top sites have changed or
been enabled/disabled isolated to the top-sites provider, since it's the class
concerned with top sites in the first place, instead of spreading it out to
`QueryContextCache`. However, by the same token I didn't want to cache contexts
directly in the provider in order to keep all context caching in
`QueryContextCache`. (Contexts are also per window/urlbar, not global, so if we
were to cache contexts in the provider, we'd need to store them in map from
windows to contexts or something similar.)

So I added a more general listener system to the provider. Listeners are called
when the top sites change or they are enabled/disabled. `QueryContextCache` adds
a listener function so it can evict its cached top-sites context. The provider
keeps weak references to the listener functions because currently `UrlbarView`
doesn't have a way to tell when it's destroyed, so it doesn't know when it
should remove listeners.

Finally, there doesn't seem to be a way to observe the `TopSitesFeed` from the
outside, and I don't think it's the role of `TopSitesFeed` to broadcast an
observer message to the entire browser or something like that, so I modified
`AboutNewTab` to subscribe to changes in its activity stream object and then
compare the new top sites to the last seen top sites, and if they're different,
then broadcast a new "newtab-top-sites-changed" notification.

Differential Revision: https://phabricator.services.mozilla.com/D134863
browser/components/urlbar/UrlbarProviderTopSites.jsm
browser/components/urlbar/UrlbarView.jsm
browser/components/urlbar/tests/browser/browser.ini
browser/components/urlbar/tests/browser/browser_queryContextCache.js [new file with mode: 0644]
browser/modules/AboutNewTab.jsm