Make sure webrtc::VideoSource is released when WebRtcVideoTrackAdapter is destroyed.
[chromium-blink-merge.git] / components / keyed_service / content / browser_context_dependency_manager.cc
blob98e4e2928f5fa35c933add376308ab5790390c35
1 // Copyright 2014 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.
5 #include "components/keyed_service/content/browser_context_dependency_manager.h"
7 #include <algorithm>
8 #include <deque>
9 #include <iterator>
11 #include "base/bind.h"
12 #include "base/debug/trace_event.h"
13 #include "components/keyed_service/content/browser_context_keyed_base_factory.h"
14 #include "content/public/browser/browser_context.h"
16 #ifndef NDEBUG
17 #include "base/command_line.h"
18 #include "base/file_util.h"
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
26 void BrowserContextDependencyManager::AddComponent(
27 BrowserContextKeyedBaseFactory* component) {
28 dependency_graph_.AddNode(component);
31 void BrowserContextDependencyManager::RemoveComponent(
32 BrowserContextKeyedBaseFactory* component) {
33 dependency_graph_.RemoveNode(component);
36 void BrowserContextDependencyManager::AddEdge(
37 BrowserContextKeyedBaseFactory* depended,
38 BrowserContextKeyedBaseFactory* dependee) {
39 dependency_graph_.AddEdge(depended, dependee);
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();
50 for (std::vector<DependencyNode*>::const_iterator it =
51 construction_order.begin();
52 it != construction_order.end();
53 ++it) {
54 BrowserContextKeyedBaseFactory* factory =
55 static_cast<BrowserContextKeyedBaseFactory*>(*it);
56 factory->RegisterProfilePrefsIfNecessaryForContext(context, pref_registry);
60 void BrowserContextDependencyManager::CreateBrowserContextServices(
61 content::BrowserContext* context) {
62 DoCreateBrowserContextServices(context, false);
65 void BrowserContextDependencyManager::CreateBrowserContextServicesForTest(
66 content::BrowserContext* context) {
67 DoCreateBrowserContextServices(context, true);
70 void BrowserContextDependencyManager::DoCreateBrowserContextServices(
71 content::BrowserContext* context,
72 bool is_testing_context) {
73 TRACE_EVENT0(
74 "browser",
75 "BrowserContextDependencyManager::DoCreateBrowserContextServices")
76 #ifndef NDEBUG
77 MarkBrowserContextLiveForTesting(context);
78 #endif
80 will_create_browser_context_services_callbacks_.Notify(context);
82 std::vector<DependencyNode*> construction_order;
83 if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
84 NOTREACHED();
87 #ifndef NDEBUG
88 DumpBrowserContextDependencies(context);
89 #endif
91 for (size_t i = 0; i < construction_order.size(); i++) {
92 BrowserContextKeyedBaseFactory* factory =
93 static_cast<BrowserContextKeyedBaseFactory*>(construction_order[i]);
94 if (is_testing_context && factory->ServiceIsNULLWhileTesting()) {
95 factory->SetEmptyTestingFactory(context);
96 } else if (factory->ServiceIsCreatedWithBrowserContext()) {
97 // Create the service.
98 factory->CreateServiceNow(context);
103 void BrowserContextDependencyManager::DestroyBrowserContextServices(
104 content::BrowserContext* context) {
105 std::vector<DependencyNode*> destruction_order;
106 if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
107 NOTREACHED();
110 #ifndef NDEBUG
111 DumpBrowserContextDependencies(context);
112 #endif
114 for (size_t i = 0; i < destruction_order.size(); i++) {
115 BrowserContextKeyedBaseFactory* factory =
116 static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]);
117 factory->BrowserContextShutdown(context);
120 #ifndef NDEBUG
121 // The context is now dead to the rest of the program.
122 dead_context_pointers_.insert(context);
123 #endif
125 for (size_t i = 0; i < destruction_order.size(); i++) {
126 BrowserContextKeyedBaseFactory* factory =
127 static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]);
128 factory->BrowserContextDestroyed(context);
132 scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
133 BrowserContextDependencyManager::
134 RegisterWillCreateBrowserContextServicesCallbackForTesting(
135 const base::Callback<void(content::BrowserContext*)>& callback) {
136 return will_create_browser_context_services_callbacks_.Add(callback);
139 #ifndef NDEBUG
140 void BrowserContextDependencyManager::AssertBrowserContextWasntDestroyed(
141 content::BrowserContext* context) {
142 if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
143 NOTREACHED() << "Attempted to access a BrowserContext that was ShutDown(). "
144 << "This is most likely a heap smasher in progress. After "
145 << "KeyedService::Shutdown() completes, your "
146 << "service MUST NOT refer to depended BrowserContext "
147 << "services again.";
151 void BrowserContextDependencyManager::MarkBrowserContextLiveForTesting(
152 content::BrowserContext* context) {
153 dead_context_pointers_.erase(context);
155 #endif
157 // static
158 BrowserContextDependencyManager*
159 BrowserContextDependencyManager::GetInstance() {
160 return Singleton<BrowserContextDependencyManager>::get();
163 BrowserContextDependencyManager::BrowserContextDependencyManager() {}
165 BrowserContextDependencyManager::~BrowserContextDependencyManager() {}
167 #ifndef NDEBUG
168 namespace {
170 std::string BrowserContextKeyedBaseFactoryGetNodeName(DependencyNode* node) {
171 return static_cast<BrowserContextKeyedBaseFactory*>(node)->name();
174 } // namespace
176 void BrowserContextDependencyManager::DumpBrowserContextDependencies(
177 content::BrowserContext* context) {
178 // Whenever we try to build a destruction ordering, we should also dump a
179 // dependency graph to "/path/to/context/context-dependencies.dot".
180 if (CommandLine::ForCurrentProcess()->HasSwitch(
181 kDumpBrowserContextDependencyGraphFlag)) {
182 base::FilePath dot_file =
183 context->GetPath().AppendASCII("browser-context-dependencies.dot");
184 std::string contents = dependency_graph_.DumpAsGraphviz(
185 "BrowserContext",
186 base::Bind(&BrowserContextKeyedBaseFactoryGetNodeName));
187 base::WriteFile(dot_file, contents.c_str(), contents.size());
190 #endif // NDEBUG