blob: 5d482eda0ed4145beb9c45c12361e24f37519122 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h"
#include <utility>
#include "base/bind.h"
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "base/task_runner_util.h"
#include "chrome/browser/performance_manager/performance_manager_impl.h"
#include "chrome/browser/performance_manager/persistence/site_data/non_recording_site_data_cache.h"
#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h"
#include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_inspector.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
namespace performance_manager {
namespace {
SiteDataCacheFactory* g_instance = nullptr;
} // namespace
SiteDataCacheFactory* SiteDataCacheFactory::GetInstance() {
return g_instance;
}
SiteDataCacheFactory::SiteDataCacheFactory() {
DETACH_FROM_SEQUENCE(sequence_checker_);
DCHECK_EQ(nullptr, g_instance);
g_instance = this;
}
SiteDataCacheFactory::~SiteDataCacheFactory() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(this, g_instance);
g_instance = nullptr;
}
// static
void SiteDataCacheFactory::OnBrowserContextCreatedOnUIThread(
SiteDataCacheFactory* factory,
content::BrowserContext* browser_context,
content::BrowserContext* parent_context) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(factory);
// As |factory| will be deleted on its task runner it's safe to pass the raw
// pointer to BindOnce, it's guaranteed that this task will run before the
// factory.
base::Optional<std::string> parent_context_id;
if (parent_context) {
DCHECK(browser_context->IsOffTheRecord());
parent_context_id = parent_context->UniqueId();
}
PerformanceManagerImpl::GetInstance()->CallOnGraphImpl(
FROM_HERE, base::BindOnce(
[](SiteDataCacheFactory* factory,
const std::string& browser_context_id,
const base::FilePath& context_path,
base::Optional<std::string> parent_context_id,
GraphImpl* graph_unused) {
factory->OnBrowserContextCreated(
browser_context_id, context_path, parent_context_id);
},
base::Unretained(factory), browser_context->UniqueId(),
browser_context->GetPath(), parent_context_id));
}
// static
void SiteDataCacheFactory::OnBrowserContextDestroyedOnUIThread(
SiteDataCacheFactory* factory,
content::BrowserContext* browser_context) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(factory);
PerformanceManagerImpl::GetInstance()->CallOnGraphImpl(
FROM_HERE, base::BindOnce(
[](SiteDataCacheFactory* factory,
const std::string& browser_context_id,
performance_manager::GraphImpl* graph_unused) {
factory->OnBrowserContextDestroyed(browser_context_id);
},
base::Unretained(factory), browser_context->UniqueId()));
}
SiteDataCache* SiteDataCacheFactory::GetDataCacheForBrowserContext(
const std::string& browser_context_id) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = data_cache_map_.find(browser_context_id);
if (it != data_cache_map_.end())
return it->second.get();
return nullptr;
}
SiteDataCacheInspector* SiteDataCacheFactory::GetInspectorForBrowserContext(
const std::string& browser_context_id) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = data_cache_inspector_map_.find(browser_context_id);
if (it != data_cache_inspector_map_.end())
return it->second;
return nullptr;
}
void SiteDataCacheFactory::SetDataCacheInspectorForBrowserContext(
SiteDataCacheInspector* inspector,
const std::string& browser_context_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (inspector) {
DCHECK_EQ(nullptr, GetInspectorForBrowserContext(browser_context_id));
data_cache_inspector_map_.emplace(
std::make_pair(browser_context_id, inspector));
} else {
DCHECK_NE(nullptr, GetInspectorForBrowserContext(browser_context_id));
data_cache_inspector_map_.erase(browser_context_id);
}
}
void SiteDataCacheFactory::IsDataCacheRecordingForTesting(
const std::string& browser_context_id,
base::OnceCallback<void(bool)> cb) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
PerformanceManagerImpl::GetInstance()->CallOnGraphImpl(
FROM_HERE,
base::BindOnce(
[](SiteDataCacheFactory* factory,
const std::string& browser_context_id,
base::OnceCallback<void(bool)> cb, GraphImpl* graph_unused) {
auto it = factory->data_cache_map_.find(browser_context_id);
CHECK(it != factory->data_cache_map_.end());
std::move(cb).Run(it->second->IsRecordingForTesting());
},
this, browser_context_id, std::move(cb)));
}
void SiteDataCacheFactory::OnBrowserContextCreated(
const std::string& browser_context_id,
const base::FilePath& context_path,
base::Optional<std::string> parent_context_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!base::Contains(data_cache_map_, browser_context_id));
if (parent_context_id) {
SiteDataCacheInspector* parent_debug =
GetInspectorForBrowserContext(parent_context_id.value());
DCHECK(parent_debug);
DCHECK(base::Contains(data_cache_map_, parent_context_id.value()));
SiteDataCache* data_cache_for_readers =
data_cache_map_[parent_context_id.value()].get();
DCHECK(data_cache_for_readers);
data_cache_map_.emplace(std::make_pair(
std::move(browser_context_id),
std::make_unique<NonRecordingSiteDataCache>(
browser_context_id, parent_debug, data_cache_for_readers)));
} else {
data_cache_map_.emplace(std::make_pair(
std::move(browser_context_id),
std::make_unique<SiteDataCacheImpl>(browser_context_id, context_path)));
}
}
void SiteDataCacheFactory::OnBrowserContextDestroyed(
const std::string& browser_context_id) {
DCHECK(base::Contains(data_cache_map_, browser_context_id));
data_cache_map_.erase(browser_context_id);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
} // namespace performance_manager