OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/profiles/profile_dependency_manager.h" | 5 #include "chrome/browser/profiles/profile_dependency_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 #include <iterator> | 9 #include <iterator> |
10 | 10 |
| 11 #include "chrome/browser/background/background_contents_service_factory.h" |
11 #include "chrome/browser/profiles/profile_keyed_service.h" | 12 #include "chrome/browser/profiles/profile_keyed_service.h" |
12 #include "chrome/browser/profiles/profile_keyed_service_factory.h" | 13 #include "chrome/browser/profiles/profile_keyed_service_factory.h" |
| 14 #include "chrome/browser/search_engines/template_url_service_factory.h" |
| 15 #include "chrome/browser/sessions/session_service_factory.h" |
| 16 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
13 #include "content/common/notification_service.h" | 17 #include "content/common/notification_service.h" |
14 | 18 |
15 class Profile; | 19 class Profile; |
16 | 20 |
| 21 namespace { |
| 22 |
| 23 bool g_initialized = false; |
| 24 |
| 25 // This method gets the instance of each ServiceFactory. We do this so that |
| 26 // each ServiceFactory initializes iteslf and registers its dependencies with |
| 27 // the global PreferenceDependencyManager. We need to have a complete |
| 28 // dependency graph when we create a profile so we can dispatch the profile |
| 29 // creation message to the services that want to create their services at |
| 30 // profile creation time. |
| 31 // |
| 32 // TODO(erg): This needs to be something else. I don't think putting every |
| 33 // FooServiceFactory here will scale or is desireable long term. |
| 34 void AssertFactoriesBuilt() { |
| 35 if (!g_initialized) { |
| 36 BackgroundContentsServiceFactory::GetInstance(); |
| 37 SessionServiceFactory::GetInstance(); |
| 38 TabRestoreServiceFactory::GetInstance(); |
| 39 TemplateURLServiceFactory::GetInstance(); |
| 40 |
| 41 g_initialized = true; |
| 42 } |
| 43 } |
| 44 |
| 45 } // namespace |
| 46 |
17 void ProfileDependencyManager::AddComponent( | 47 void ProfileDependencyManager::AddComponent( |
18 ProfileKeyedServiceFactory* component) { | 48 ProfileKeyedServiceFactory* component) { |
19 all_components_.push_back(component); | 49 all_components_.push_back(component); |
20 destruction_order_.clear(); | 50 destruction_order_.clear(); |
21 } | 51 } |
22 | 52 |
23 void ProfileDependencyManager::RemoveComponent( | 53 void ProfileDependencyManager::RemoveComponent( |
24 ProfileKeyedServiceFactory* component) { | 54 ProfileKeyedServiceFactory* component) { |
25 all_components_.erase(std::remove(all_components_.begin(), | 55 all_components_.erase(std::remove(all_components_.begin(), |
26 all_components_.end(), | 56 all_components_.end(), |
(...skipping 12 matching lines...) Expand all Loading... |
39 | 69 |
40 destruction_order_.clear(); | 70 destruction_order_.clear(); |
41 } | 71 } |
42 | 72 |
43 void ProfileDependencyManager::AddEdge(ProfileKeyedServiceFactory* depended, | 73 void ProfileDependencyManager::AddEdge(ProfileKeyedServiceFactory* depended, |
44 ProfileKeyedServiceFactory* dependee) { | 74 ProfileKeyedServiceFactory* dependee) { |
45 edges_.insert(std::make_pair(depended, dependee)); | 75 edges_.insert(std::make_pair(depended, dependee)); |
46 destruction_order_.clear(); | 76 destruction_order_.clear(); |
47 } | 77 } |
48 | 78 |
| 79 void ProfileDependencyManager::CreateProfileServices(Profile* profile, |
| 80 bool is_testing_profile) { |
| 81 #ifndef NDEBUG |
| 82 // Unmark |profile| as dead. This exists because of unit tests, which will |
| 83 // often have similar stack structures. 0xWhatever might be created, go out |
| 84 // of scope, and then a new Profile object might be created at 0xWhatever. |
| 85 dead_profile_pointers_.erase(profile); |
| 86 #endif |
| 87 |
| 88 AssertFactoriesBuilt(); |
| 89 |
| 90 if (destruction_order_.empty()) |
| 91 BuildDestructionOrder(); |
| 92 |
| 93 // Iterate in reverse destruction order for creation. |
| 94 for (std::vector<ProfileKeyedServiceFactory*>::reverse_iterator rit = |
| 95 destruction_order_.rbegin(); rit != destruction_order_.rend(); |
| 96 ++rit) { |
| 97 if (is_testing_profile && (*rit)->ServiceIsNULLWhileTesting()) { |
| 98 (*rit)->SetTestingFactory(profile, NULL); |
| 99 } else if ((*rit)->ServiceIsCreatedWithProfile()) { |
| 100 // Create the service. |
| 101 (*rit)->GetServiceForProfile(profile, true); |
| 102 } |
| 103 } |
| 104 } |
| 105 |
49 void ProfileDependencyManager::DestroyProfileServices(Profile* profile) { | 106 void ProfileDependencyManager::DestroyProfileServices(Profile* profile) { |
50 if (destruction_order_.empty()) | 107 if (destruction_order_.empty()) |
51 BuildDestructionOrder(); | 108 BuildDestructionOrder(); |
52 | 109 |
53 for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it = | 110 for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it = |
54 destruction_order_.begin(); it != destruction_order_.end(); ++it) { | 111 destruction_order_.begin(); it != destruction_order_.end(); ++it) { |
55 (*it)->ProfileShutdown(profile); | 112 (*it)->ProfileShutdown(profile); |
56 } | 113 } |
57 | 114 |
58 #ifndef NDEBUG | 115 #ifndef NDEBUG |
59 // The profile is now dead to the rest of the program. | 116 // The profile is now dead to the rest of the program. |
60 dead_profile_pointers_.insert(profile); | 117 dead_profile_pointers_.insert(profile); |
61 #endif | 118 #endif |
62 | 119 |
63 for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it = | 120 for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it = |
64 destruction_order_.begin(); it != destruction_order_.end(); ++it) { | 121 destruction_order_.begin(); it != destruction_order_.end(); ++it) { |
65 (*it)->ProfileDestroyed(profile); | 122 (*it)->ProfileDestroyed(profile); |
66 } | 123 } |
67 } | 124 } |
68 | 125 |
69 #ifndef NDEBUG | 126 #ifndef NDEBUG |
70 void ProfileDependencyManager::ProfileNowExists(Profile* profile) { | |
71 dead_profile_pointers_.erase(profile); | |
72 } | |
73 | |
74 void ProfileDependencyManager::AssertProfileWasntDestroyed(Profile* profile) { | 127 void ProfileDependencyManager::AssertProfileWasntDestroyed(Profile* profile) { |
75 if (dead_profile_pointers_.find(profile) != dead_profile_pointers_.end()) { | 128 if (dead_profile_pointers_.find(profile) != dead_profile_pointers_.end()) { |
76 NOTREACHED() << "Attempted to access a Profile that was ShutDown(). This " | 129 NOTREACHED() << "Attempted to access a Profile that was ShutDown(). This " |
77 << "is most likely a heap smasher in progress. After " | 130 << "is most likely a heap smasher in progress. After " |
78 << "ProfileKeyedService::Shutdown() completes, your service " | 131 << "ProfileKeyedService::Shutdown() completes, your service " |
79 << "MUST NOT refer to depended Profile services again."; | 132 << "MUST NOT refer to depended Profile services again."; |
80 } | 133 } |
81 } | 134 } |
82 #endif | 135 #endif |
83 | 136 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 } | 187 } |
135 } | 188 } |
136 | 189 |
137 if (edges.size()) { | 190 if (edges.size()) { |
138 NOTREACHED() << "Dependency graph has a cycle. We are doomed."; | 191 NOTREACHED() << "Dependency graph has a cycle. We are doomed."; |
139 } | 192 } |
140 | 193 |
141 std::reverse(output.begin(), output.end()); | 194 std::reverse(output.begin(), output.end()); |
142 destruction_order_ = output; | 195 destruction_order_ = output; |
143 } | 196 } |
OLD | NEW |