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