Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / components / browser_context_keyed_service / browser_context_dependency_manager.cc
1 // Copyright (c) 2013 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/browser_context_keyed_service/browser_context_dependency_manager.h"
6
7 #include <algorithm>
8 #include <deque>
9 #include <iterator>
10
11 #include "base/bind.h"
12 #include "base/debug/trace_event.h"
13 #include "components/browser_context_keyed_service/browser_context_keyed_base_factory.h"
14 #include "content/public/browser/browser_context.h"
15
16 #ifndef NDEBUG
17 #include "base/command_line.h"
18 #include "base/file_util.h"
19
20 // Dumps dependency information about our browser context keyed services
21 // into a dot file in the browser context directory.
22 const char kDumpBrowserContextDependencyGraphFlag[] =
23     "dump-browser-context-graph";
24 #endif  // NDEBUG
25
26 void BrowserContextDependencyManager::AddComponent(
27     BrowserContextKeyedBaseFactory* component) {
28   dependency_graph_.AddNode(component);
29 }
30
31 void BrowserContextDependencyManager::RemoveComponent(
32     BrowserContextKeyedBaseFactory* component) {
33   dependency_graph_.RemoveNode(component);
34 }
35
36 void BrowserContextDependencyManager::AddEdge(
37     BrowserContextKeyedBaseFactory* depended,
38     BrowserContextKeyedBaseFactory* dependee) {
39   dependency_graph_.AddEdge(depended, dependee);
40 }
41
42 void BrowserContextDependencyManager::RegisterProfilePrefsForServices(
43     const content::BrowserContext* context,
44     user_prefs::PrefRegistrySyncable* pref_registry) {
45   std::vector<DependencyNode*> construction_order;
46   if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
47     NOTREACHED();
48   }
49
50   for (std::vector<DependencyNode*>::const_iterator it =
51            construction_order.begin(); it != construction_order.end(); ++it) {
52     BrowserContextKeyedBaseFactory* factory =
53         static_cast<BrowserContextKeyedBaseFactory*>(*it);
54     factory->RegisterProfilePrefsIfNecessaryForContext(context, pref_registry);
55   }
56 }
57
58 void BrowserContextDependencyManager::CreateBrowserContextServices(
59     content::BrowserContext* context) {
60   DoCreateBrowserContextServices(context, false);
61 }
62
63 void BrowserContextDependencyManager::CreateBrowserContextServicesForTest(
64     content::BrowserContext* context) {
65   DoCreateBrowserContextServices(context, true);
66 }
67
68 void BrowserContextDependencyManager::DoCreateBrowserContextServices(
69     content::BrowserContext* context,
70     bool is_testing_context) {
71   TRACE_EVENT0("browser",
72     "BrowserContextDependencyManager::DoCreateBrowserContextServices")
73 #ifndef NDEBUG
74   MarkBrowserContextLiveForTesting(context);
75 #endif
76
77   std::vector<DependencyNode*> construction_order;
78   if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
79     NOTREACHED();
80   }
81
82 #ifndef NDEBUG
83   DumpBrowserContextDependencies(context);
84 #endif
85
86   for (size_t i = 0; i < construction_order.size(); i++) {
87     BrowserContextKeyedBaseFactory* factory =
88         static_cast<BrowserContextKeyedBaseFactory*>(construction_order[i]);
89     if (is_testing_context && factory->ServiceIsNULLWhileTesting()) {
90       factory->SetEmptyTestingFactory(context);
91     } else if (factory->ServiceIsCreatedWithBrowserContext()) {
92       // Create the service.
93       factory->CreateServiceNow(context);
94     }
95   }
96 }
97
98 void BrowserContextDependencyManager::DestroyBrowserContextServices(
99     content::BrowserContext* context) {
100   std::vector<DependencyNode*> destruction_order;
101   if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
102     NOTREACHED();
103   }
104
105 #ifndef NDEBUG
106   DumpBrowserContextDependencies(context);
107 #endif
108
109   for (size_t i = 0; i < destruction_order.size(); i++) {
110     BrowserContextKeyedBaseFactory* factory =
111         static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]);
112     factory->BrowserContextShutdown(context);
113   }
114
115 #ifndef NDEBUG
116   // The context is now dead to the rest of the program.
117   dead_context_pointers_.insert(context);
118 #endif
119
120   for (size_t i = 0; i < destruction_order.size(); i++) {
121     BrowserContextKeyedBaseFactory* factory =
122         static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]);
123     factory->BrowserContextDestroyed(context);
124   }
125 }
126
127 #ifndef NDEBUG
128 void BrowserContextDependencyManager::AssertBrowserContextWasntDestroyed(
129     content::BrowserContext* context) {
130   if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
131     NOTREACHED() << "Attempted to access a BrowserContext that was ShutDown(). "
132                  << "This is most likely a heap smasher in progress. After "
133                  << "BrowserContextKeyedService::Shutdown() completes, your "
134                  << "service MUST NOT refer to depended BrowserContext "
135                  << "services again.";
136   }
137 }
138
139 void BrowserContextDependencyManager::MarkBrowserContextLiveForTesting(
140     content::BrowserContext* context) {
141   dead_context_pointers_.erase(context);
142 }
143 #endif
144
145 // static
146 BrowserContextDependencyManager*
147 BrowserContextDependencyManager::GetInstance() {
148   return Singleton<BrowserContextDependencyManager>::get();
149 }
150
151 BrowserContextDependencyManager::BrowserContextDependencyManager() {
152 }
153
154 BrowserContextDependencyManager::~BrowserContextDependencyManager() {
155 }
156
157 #ifndef NDEBUG
158 namespace {
159
160 std::string BrowserContextKeyedBaseFactoryGetNodeName(DependencyNode* node) {
161   return static_cast<BrowserContextKeyedBaseFactory*>(node)->name();
162 }
163
164 }  // namespace
165
166 void BrowserContextDependencyManager::DumpBrowserContextDependencies(
167     content::BrowserContext* context) {
168   // Whenever we try to build a destruction ordering, we should also dump a
169   // dependency graph to "/path/to/context/context-dependencies.dot".
170   if (CommandLine::ForCurrentProcess()->HasSwitch(
171           kDumpBrowserContextDependencyGraphFlag)) {
172     base::FilePath dot_file =
173         context->GetPath().AppendASCII("browser-context-dependencies.dot");
174     std::string contents = dependency_graph_.DumpAsGraphviz(
175         "BrowserContext",
176         base::Bind(&BrowserContextKeyedBaseFactoryGetNodeName));
177     file_util::WriteFile(dot_file, contents.c_str(), contents.size());
178   }
179 }
180 #endif  // NDEBUG