| // 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 |