blob: 8241e23c64bfd00a7da31755ae9d04e5a24a2215 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/web_cache/browser/web_cache_manager.h"
#include "base/no_destructor.h"
namespace web_cache {
// static
WebCacheManager* WebCacheManager::GetInstance() {
static base::NoDestructor<WebCacheManager> s_instance;
return s_instance.get();
}
WebCacheManager::WebCacheManager() {
// The instance can be created once renderers are already running, thus we
// cannot observe the creation of the previous processes.
for (auto iter(content::RenderProcessHost::AllHostsIterator());
!iter.IsAtEnd(); iter.Advance()) {
content::RenderProcessHost* process_host = iter.GetCurrentValue();
OnRenderProcessHostCreated(process_host);
if (process_host->IsReady()) {
RenderProcessReady(process_host);
}
}
}
WebCacheManager::~WebCacheManager() = default;
void WebCacheManager::Add(content::RenderProcessHost* process_host) {
mojo::Remote<mojom::WebCache> service;
process_host->BindReceiver(service.BindNewPipeAndPassReceiver());
web_cache_services_[process_host->GetID()] = std::move(service);
}
void WebCacheManager::Remove(content::RenderProcessHost* process_host) {
web_cache_services_.erase(process_host->GetID());
}
void WebCacheManager::ClearCache() {
// Tell each renderer process to clear the cache.
ClearRendererCache(INSTANTLY);
}
void WebCacheManager::ClearCacheOnNavigation() {
// Tell each renderer process to clear the cache when a tab is reloaded or
// the user navigates to a new website.
ClearRendererCache(ON_NAVIGATION);
}
void WebCacheManager::OnRenderProcessHostCreated(
content::RenderProcessHost* process_host) {
// If the host is reused after the process exited, it is possible to get a
// second created notification for the same host.
if (!rph_observations_.IsObservingSource(process_host)) {
rph_observations_.AddObservation(process_host);
}
}
void WebCacheManager::RenderProcessReady(
content::RenderProcessHost* process_host) {
Add(process_host);
}
void WebCacheManager::RenderProcessExited(
content::RenderProcessHost* process_host,
const content::ChildProcessTerminationInfo& info) {
RenderProcessHostDestroyed(process_host);
}
void WebCacheManager::RenderProcessHostDestroyed(
content::RenderProcessHost* process_host) {
rph_observations_.RemoveObservation(process_host);
Remove(process_host);
}
void WebCacheManager::ClearCacheForProcess(content::ChildProcessId process_id) {
auto it = web_cache_services_.find(process_id);
if (it != web_cache_services_.end() &&
content::RenderProcessHost::FromID(process_id)->IsReady()) {
it->second->ClearCache(false);
}
}
void WebCacheManager::ClearRendererCache(
WebCacheManager::ClearCacheOccasion occasion) {
for (auto& service : web_cache_services_) {
// It is possible to have a renderer host that is not ready and is still
// present in 'web_cache_services_' because the notification has not reach
// this instance. This can happen if 'ClearRendererCache' is called by an
// other observer during 'RenderProcessHostImpl::ProcessDied'.
if (content::RenderProcessHost::FromID(service.first)->IsReady()) {
service.second->ClearCache(occasion == ON_NAVIGATION);
}
}
}
} // namespace web_cache