1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/performance_manager/persistence/site_data/site_data_cache_factory.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/sequenced_task_runner.h"
11 #include "base/stl_util.h"
12 #include "base/task_runner_util.h"
13 #include "components/performance_manager/performance_manager_impl.h"
14 #include "components/performance_manager/persistence/site_data/non_recording_site_data_cache.h"
15 #include "components/performance_manager/persistence/site_data/site_data_cache_impl.h"
16 #include "components/performance_manager/persistence/site_data/site_data_cache_inspector.h"
17 #include "content/public/browser/browser_context.h"
18 #include "content/public/browser/browser_thread.h"
19
20 namespace performance_manager {
21
22 namespace {
23 SiteDataCacheFactory* g_instance = nullptr;
24 } // namespace
25
SiteDataCacheFactory()26 SiteDataCacheFactory::SiteDataCacheFactory() {
27 DCHECK(!g_instance);
28 g_instance = this;
29 }
30
~SiteDataCacheFactory()31 SiteDataCacheFactory::~SiteDataCacheFactory() {
32 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
33 DCHECK_EQ(this, g_instance);
34 // Clear the cache map before unsetting |g_instance| as this will cause some
35 // calls to |SetDataCacheInspectorForBrowserContext|.
36 data_cache_map_.clear();
37 for (const auto& iter : data_cache_map_)
38 DCHECK_EQ(0, iter.second->Size());
39 g_instance = nullptr;
40 }
41
42 // static
GetInstance()43 SiteDataCacheFactory* SiteDataCacheFactory::GetInstance() {
44 return g_instance;
45 }
46
GetDataCacheForBrowserContext(const std::string & browser_context_id) const47 SiteDataCache* SiteDataCacheFactory::GetDataCacheForBrowserContext(
48 const std::string& browser_context_id) const {
49 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
50 auto it = data_cache_map_.find(browser_context_id);
51 if (it != data_cache_map_.end())
52 return it->second.get();
53 return nullptr;
54 }
55
GetInspectorForBrowserContext(const std::string & browser_context_id) const56 SiteDataCacheInspector* SiteDataCacheFactory::GetInspectorForBrowserContext(
57 const std::string& browser_context_id) const {
58 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
59 auto it = data_cache_inspector_map_.find(browser_context_id);
60 if (it != data_cache_inspector_map_.end())
61 return it->second;
62 return nullptr;
63 }
64
SetDataCacheInspectorForBrowserContext(SiteDataCacheInspector * inspector,const std::string & browser_context_id)65 void SiteDataCacheFactory::SetDataCacheInspectorForBrowserContext(
66 SiteDataCacheInspector* inspector,
67 const std::string& browser_context_id) {
68 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
69 if (inspector) {
70 DCHECK_EQ(nullptr, GetInspectorForBrowserContext(browser_context_id));
71 data_cache_inspector_map_.emplace(
72 std::make_pair(browser_context_id, inspector));
73 } else {
74 DCHECK_NE(nullptr, GetInspectorForBrowserContext(browser_context_id));
75 data_cache_inspector_map_.erase(browser_context_id);
76 }
77 }
78
IsDataCacheRecordingForTesting(const std::string & browser_context_id)79 bool SiteDataCacheFactory::IsDataCacheRecordingForTesting(
80 const std::string& browser_context_id) {
81 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
82 auto it = data_cache_map_.find(browser_context_id);
83 CHECK(it != data_cache_map_.end());
84 return it->second->IsRecording();
85 }
86
SetCacheForTesting(const std::string & browser_context_id,std::unique_ptr<SiteDataCache> cache)87 void SiteDataCacheFactory::SetCacheForTesting(
88 const std::string& browser_context_id,
89 std::unique_ptr<SiteDataCache> cache) {
90 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
91
92 data_cache_map_.erase(browser_context_id);
93 data_cache_map_.emplace(browser_context_id, std::move(cache));
94 }
95
SetCacheInspectorForTesting(const std::string & browser_context_id,SiteDataCacheInspector * inspector)96 void SiteDataCacheFactory::SetCacheInspectorForTesting(
97 const std::string& browser_context_id,
98 SiteDataCacheInspector* inspector) {
99 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
100 DCHECK(!base::Contains(data_cache_inspector_map_, browser_context_id));
101 data_cache_inspector_map_.emplace(browser_context_id, inspector);
102 }
103
OnBrowserContextCreated(const std::string & browser_context_id,const base::FilePath & context_path,base::Optional<std::string> parent_context_id)104 void SiteDataCacheFactory::OnBrowserContextCreated(
105 const std::string& browser_context_id,
106 const base::FilePath& context_path,
107 base::Optional<std::string> parent_context_id) {
108 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
109
110 DCHECK(!base::Contains(data_cache_map_, browser_context_id));
111
112 if (parent_context_id) {
113 SiteDataCacheInspector* parent_debug =
114 GetInspectorForBrowserContext(parent_context_id.value());
115 DCHECK(parent_debug);
116 DCHECK(base::Contains(data_cache_map_, parent_context_id.value()));
117 SiteDataCache* data_cache_for_readers =
118 data_cache_map_[parent_context_id.value()].get();
119 DCHECK(data_cache_for_readers);
120 data_cache_map_.emplace(
121 std::move(browser_context_id),
122 std::make_unique<NonRecordingSiteDataCache>(
123 browser_context_id, parent_debug, data_cache_for_readers));
124 } else {
125 data_cache_map_.emplace(
126 std::move(browser_context_id),
127 std::make_unique<SiteDataCacheImpl>(browser_context_id, context_path));
128 }
129 }
130
OnBrowserContextDestroyed(const std::string & browser_context_id)131 void SiteDataCacheFactory::OnBrowserContextDestroyed(
132 const std::string& browser_context_id) {
133 DCHECK(base::Contains(data_cache_map_, browser_context_id));
134 data_cache_map_.erase(browser_context_id);
135 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
136 }
137
138 } // namespace performance_manager
139