Bug 1948814 - Part 1: Fix content-only mode of imgICache.clearCache, and add explicit clear-both mode. r=tnikkel,anti-tracking-reviewers,emz

Differential Revision: https://phabricator.services.mozilla.com/D238578
This commit is contained in:
Tooru Fujisawa
2025-02-20 07:04:53 +00:00
parent b3319016c8
commit b7ffedd05c
12 changed files with 50 additions and 32 deletions

View File

@@ -2129,7 +2129,7 @@ mozilla::ipc::IPCResult ContentChild::RecvClearImageCacheFromSite(
}
mozilla::ipc::IPCResult ContentChild::RecvClearImageCache(
const bool& privateLoader, const bool& chrome) {
const bool& privateLoader, const mozilla::Maybe<bool>& chrome) {
imgLoader* loader = privateLoader ? imgLoader::PrivateBrowsingLoader()
: imgLoader::NormalLoader();

View File

@@ -260,7 +260,7 @@ class ContentChild final : public PContentChild,
const nsCString& aSchemelessSite,
const OriginAttributesPattern& aPattern);
mozilla::ipc::IPCResult RecvClearImageCache(const bool& privateLoader,
const bool& chrome);
const Maybe<bool>& chrome);
PRemoteSpellcheckEngineChild* AllocPRemoteSpellcheckEngineChild();

View File

@@ -653,7 +653,7 @@ child:
async ClearImageCacheFromSite(nsCString aSchemelessSite, OriginAttributesPattern aPattern);
async ClearImageCache(bool privateLoader, bool chrome);
async ClearImageCache(bool privateLoader, bool? chrome);
async ClearStyleSheetCache(nullable nsIPrincipal? aPrincipal,
nsCString? aSchemelessSite,

View File

@@ -448,10 +448,8 @@ bool gfxWindowsPlatform::HandleDeviceReset() {
// Remove devices and adapters.
DeviceManagerDx::Get()->ResetDevices();
imgLoader::NormalLoader()->ClearCache(true);
imgLoader::NormalLoader()->ClearCache(false);
imgLoader::PrivateBrowsingLoader()->ClearCache(true);
imgLoader::PrivateBrowsingLoader()->ClearCache(false);
imgLoader::NormalLoader()->ClearCache();
imgLoader::PrivateBrowsingLoader()->ClearCache();
gfxAlphaBoxBlur::ShutdownBlurCache();
gfxConfig::Reset(Feature::D3D11_COMPOSITING);

View File

@@ -34,10 +34,14 @@ interface imgICache : nsISupports
/**
* Evict images from the cache.
*
* @param chrome If TRUE, evict only chrome images.
* If FALSE, evict everything except chrome images.
* @param chrome If passed and TRUE, evict only chrome images.
* If passed and FALSE, evict everything except chrome images.
* If not passed, evict all images.
*
* NOTE: Given that XPIDL doesn't support "was-not-passed" state for boolean,
* the chrome parameter uses jsval instead of boolean.
*/
void clearCache(in boolean chrome);
void clearCache([optional] in jsval chrome);
/**
* Evict images from the cache.

View File

@@ -1372,7 +1372,12 @@ imgLoader::Observe(nsISupports* aSubject, const char* aTopic,
}
NS_IMETHODIMP
imgLoader::ClearCache(bool chrome) {
imgLoader::ClearCache(JS::Handle<JS::Value> chrome) {
return ClearCache(chrome.isBoolean() ? Some(chrome.toBoolean()) : Nothing());
}
NS_IMETHODIMP
imgLoader::ClearCache(Maybe<bool> chrome) {
if (XRE_IsParentProcess()) {
bool privateLoader = this == gPrivateBrowsingLoader;
for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
@@ -1381,7 +1386,11 @@ imgLoader::ClearCache(bool chrome) {
}
ClearOptions options;
if (chrome) {
if (*chrome) {
options += ClearOption::ChromeOnly;
} else {
options += ClearOption::ContentOnly;
}
}
return ClearImageCache(options);
}
@@ -2148,11 +2157,19 @@ bool imgLoader::RemoveFromCache(imgCacheEntry* entry, QueueState aQueueState) {
nsresult imgLoader::ClearImageCache(ClearOptions aOptions) {
const bool chromeOnly = aOptions.contains(ClearOption::ChromeOnly);
const bool contentOnly = aOptions.contains(ClearOption::ContentOnly);
const auto ShouldRemove = [&](imgCacheEntry* aEntry) {
if (chromeOnly) {
if (chromeOnly || contentOnly) {
// TODO: Consider also removing "resource://" etc?
RefPtr<imgRequest> request = aEntry->GetRequest();
if (!request || !request->CacheKey().URI()->SchemeIs("chrome")) {
if (!request) {
return false;
}
bool isChrome = request->CacheKey().URI()->SchemeIs("chrome");
if (chromeOnly && !isChrome) {
return false;
}
if (contentOnly && isChrome) {
return false;
}
}
@@ -2176,7 +2193,7 @@ nsresult imgLoader::ClearImageCache(ClearOptions aOptions) {
}
}
MOZ_ASSERT(chromeOnly || mCacheQueue.GetNumElements() == 0);
MOZ_ASSERT(chromeOnly || contentOnly || mCacheQueue.GetNumElements() == 0);
return NS_OK;
}
@@ -2193,7 +2210,7 @@ nsresult imgLoader::ClearImageCache(ClearOptions aOptions) {
return NS_ERROR_FAILURE;
}
}
MOZ_ASSERT(chromeOnly || mCache.IsEmpty());
MOZ_ASSERT(chromeOnly || contentOnly || mCache.IsEmpty());
return NS_OK;
}

View File

@@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/CORSMode.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
#include "mozilla/EnumSet.h"
#include "mozilla/UniquePtr.h"
@@ -143,11 +144,11 @@ class imgCacheEntry {
#include <vector>
#define NS_IMGLOADER_CID \
{ /* c1354898-e3fe-4602-88a7-c4520c21cb4e */ \
0xc1354898, 0xe3fe, 0x4602, { \
0x88, 0xa7, 0xc4, 0x52, 0x0c, 0x21, 0xcb, 0x4e \
} \
}
{/* c1354898-e3fe-4602-88a7-c4520c21cb4e */ \
0xc1354898, \
0xe3fe, \
0x4602, \
{0x88, 0xa7, 0xc4, 0x52, 0x0c, 0x21, 0xcb, 0x4e}}
class imgCacheQueue {
public:
@@ -243,6 +244,8 @@ class imgLoader final : public imgILoader,
imgLoader();
nsresult Init();
nsresult ClearCache(mozilla::Maybe<bool> chrome);
bool IsImageAvailable(nsIURI*, nsIPrincipal* aTriggeringPrincipal,
mozilla::CORSMode, mozilla::dom::Document*);
@@ -287,6 +290,7 @@ class imgLoader final : public imgILoader,
enum class ClearOption {
ChromeOnly,
ContentOnly,
UnusedOnly,
};
using ClearOptions = mozilla::EnumSet<ClearOption>;

View File

@@ -10,8 +10,7 @@ function clearAllImageCaches() {
SpecialPowers.Ci.imgITools
);
var imageCache = tools.getImgCacheForDocument(window.document);
imageCache.clearCache(true); // true=chrome
imageCache.clearCache(false); // false=content
imageCache.clearCache(); // no parameter=all
}
// Helper function to clear the image cache of content images

View File

@@ -131,8 +131,7 @@ function run_loadImage_tests() {
}
for (let loader of [gPublicLoader, gPrivateLoader]) {
loader.QueryInterface(Ci.imgICache).clearCache(true);
loader.QueryInterface(Ci.imgICache).clearCache(false);
loader.QueryInterface(Ci.imgICache).clearCache(); // no parameter=all
}
Services.obs.addObserver(observer, "cacheservice:empty-cache");
let cs = Services.cache2;

View File

@@ -78,8 +78,7 @@ add_task(async function () {
SpecialPowers.Ci.imgITools
);
let imageCache = tools.getImgCacheForDocument(window.document);
imageCache.clearCache(true); // true=chrome
imageCache.clearCache(false); // false=content
imageCache.clearCache(); // no parameter=all
Services.cache2.clear();
info("Enabling network state partitioning");

View File

@@ -56,8 +56,7 @@ add_task(async function () {
let imageCache = Cc["@mozilla.org/image/tools;1"]
.getService(Ci.imgITools)
.getImgCacheForDocument(null);
imageCache.clearCache(true); // true=chrome
imageCache.clearCache(false); // false=content
imageCache.clearCache(); // no parameter=all
Services.cache2.clear();
info("Reset the hits count");

View File

@@ -114,8 +114,7 @@ function cleanup() {
let imageCache = Cc["@mozilla.org/image/tools;1"]
.getService(Ci.imgITools)
.getImgCacheForDocument(null);
imageCache.clearCache(false);
imageCache.clearCache(true);
imageCache.clearCache(); // no parameter=all
}
add_setup(function () {