OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/chrome_browser_main_extra_parts_profiles.h" |
6 | |
7 #include <algorithm> | |
8 #include <deque> | |
9 #include <iterator> | |
10 | 6 |
11 #include "apps/app_restore_service_factory.h" | 7 #include "apps/app_restore_service_factory.h" |
12 #include "apps/shortcut_manager_factory.h" | 8 #include "apps/shortcut_manager_factory.h" |
13 #include "chrome/browser/autofill/autocheckout_whitelist_manager_factory.h" | 9 #include "chrome/browser/autofill/autocheckout_whitelist_manager_factory.h" |
14 #include "chrome/browser/autofill/personal_data_manager_factory.h" | 10 #include "chrome/browser/autofill/personal_data_manager_factory.h" |
15 #include "chrome/browser/background/background_contents_service_factory.h" | 11 #include "chrome/browser/background/background_contents_service_factory.h" |
16 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 12 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| 13 #include "chrome/browser/chrome_browser_main.h" |
17 #include "chrome/browser/content_settings/cookie_settings.h" | 14 #include "chrome/browser/content_settings/cookie_settings.h" |
18 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" | 15 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" |
19 #include "chrome/browser/download/download_service_factory.h" | 16 #include "chrome/browser/download/download_service_factory.h" |
20 #include "chrome/browser/extensions/activity_log.h" | 17 #include "chrome/browser/extensions/activity_log.h" |
21 #include "chrome/browser/extensions/api/alarms/alarm_manager.h" | 18 #include "chrome/browser/extensions/api/alarms/alarm_manager.h" |
22 #include "chrome/browser/extensions/api/audio/audio_api.h" | 19 #include "chrome/browser/extensions/api/audio/audio_api.h" |
23 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_factory.h" | 20 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_factory.h" |
24 #include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h" | 21 #include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h" |
25 #include "chrome/browser/extensions/api/commands/command_service.h" | 22 #include "chrome/browser/extensions/api/commands/command_service.h" |
26 #include "chrome/browser/extensions/api/cookies/cookies_api.h" | 23 #include "chrome/browser/extensions/api/cookies/cookies_api.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 #include "chrome/browser/password_manager/password_store_factory.h" | 56 #include "chrome/browser/password_manager/password_store_factory.h" |
60 #include "chrome/browser/plugins/plugin_prefs_factory.h" | 57 #include "chrome/browser/plugins/plugin_prefs_factory.h" |
61 #include "chrome/browser/policy/profile_policy_connector_factory.h" | 58 #include "chrome/browser/policy/profile_policy_connector_factory.h" |
62 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h" | 59 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h" |
63 #include "chrome/browser/predictors/predictor_database_factory.h" | 60 #include "chrome/browser/predictors/predictor_database_factory.h" |
64 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" | 61 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" |
65 #include "chrome/browser/prerender/prerender_link_manager_factory.h" | 62 #include "chrome/browser/prerender/prerender_link_manager_factory.h" |
66 #include "chrome/browser/prerender/prerender_manager_factory.h" | 63 #include "chrome/browser/prerender/prerender_manager_factory.h" |
67 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.
h" | 64 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.
h" |
68 #include "chrome/browser/profiles/gaia_info_update_service_factory.h" | 65 #include "chrome/browser/profiles/gaia_info_update_service_factory.h" |
69 #include "chrome/browser/profiles/profile.h" | |
70 #include "chrome/browser/profiles/profile_keyed_service.h" | |
71 #include "chrome/browser/profiles/profile_keyed_service_factory.h" | |
72 #include "chrome/browser/search_engines/template_url_fetcher_factory.h" | 66 #include "chrome/browser/search_engines/template_url_fetcher_factory.h" |
73 #include "chrome/browser/search_engines/template_url_service_factory.h" | 67 #include "chrome/browser/search_engines/template_url_service_factory.h" |
74 #include "chrome/browser/sessions/session_service_factory.h" | 68 #include "chrome/browser/sessions/session_service_factory.h" |
75 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 69 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
76 #include "chrome/browser/signin/about_signin_internals_factory.h" | 70 #include "chrome/browser/signin/about_signin_internals_factory.h" |
77 #include "chrome/browser/signin/signin_manager_factory.h" | 71 #include "chrome/browser/signin/signin_manager_factory.h" |
78 #include "chrome/browser/signin/token_service_factory.h" | 72 #include "chrome/browser/signin/token_service_factory.h" |
79 #include "chrome/browser/speech/chrome_speech_recognition_preferences.h" | 73 #include "chrome/browser/speech/chrome_speech_recognition_preferences.h" |
80 #include "chrome/browser/speech/extension_api/tts_extension_api.h" | 74 #include "chrome/browser/speech/extension_api/tts_extension_api.h" |
81 #include "chrome/browser/spellchecker/spellcheck_factory.h" | 75 #include "chrome/browser/spellchecker/spellcheck_factory.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 109 |
116 #if defined(USE_AURA) | 110 #if defined(USE_AURA) |
117 #include "chrome/browser/ui/gesture_prefs_observer_factory_aura.h" | 111 #include "chrome/browser/ui/gesture_prefs_observer_factory_aura.h" |
118 #endif | 112 #endif |
119 | 113 |
120 #if !defined(OS_ANDROID) | 114 #if !defined(OS_ANDROID) |
121 #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h" | 115 #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h" |
122 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_fac
tory.h" | 116 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_fac
tory.h" |
123 #endif | 117 #endif |
124 | 118 |
125 #ifndef NDEBUG | 119 namespace chrome { |
126 #include "base/command_line.h" | |
127 #include "base/file_util.h" | |
128 #include "chrome/common/chrome_switches.h" | |
129 #endif | |
130 | 120 |
131 class Profile; | 121 void AddProfilesExtraParts(ChromeBrowserMainParts* main_parts) { |
132 | 122 main_parts->AddParts(new ChromeBrowserMainExtraPartsProfiles()); |
133 void ProfileDependencyManager::AddComponent( | |
134 ProfileKeyedBaseFactory* component) { | |
135 dependency_graph_.AddNode(component); | |
136 } | 123 } |
137 | 124 |
138 void ProfileDependencyManager::RemoveComponent( | 125 } // namespace chrome |
139 ProfileKeyedBaseFactory* component) { | 126 |
140 dependency_graph_.RemoveNode(component); | 127 ChromeBrowserMainExtraPartsProfiles::ChromeBrowserMainExtraPartsProfiles() { |
141 } | 128 } |
142 | 129 |
143 void ProfileDependencyManager::AddEdge(ProfileKeyedBaseFactory* depended, | 130 ChromeBrowserMainExtraPartsProfiles::~ChromeBrowserMainExtraPartsProfiles() { |
144 ProfileKeyedBaseFactory* dependee) { | |
145 dependency_graph_.AddEdge(depended, dependee); | |
146 } | 131 } |
147 | 132 |
148 void ProfileDependencyManager::CreateProfileServices(Profile* profile, | |
149 bool is_testing_profile) { | |
150 #ifndef NDEBUG | |
151 // Unmark |profile| as dead. This exists because of unit tests, which will | |
152 // often have similar stack structures. 0xWhatever might be created, go out | |
153 // of scope, and then a new Profile object might be created at 0xWhatever. | |
154 dead_profile_pointers_.erase(profile); | |
155 #endif | |
156 | |
157 AssertFactoriesBuilt(); | |
158 | |
159 std::vector<DependencyNode*> construction_order; | |
160 if (!dependency_graph_.GetConstructionOrder(&construction_order)) { | |
161 NOTREACHED(); | |
162 } | |
163 | |
164 #ifndef NDEBUG | |
165 DumpProfileDependencies(profile); | |
166 #endif | |
167 | |
168 for (size_t i = 0; i < construction_order.size(); i++) { | |
169 ProfileKeyedBaseFactory* factory = | |
170 static_cast<ProfileKeyedBaseFactory*>(construction_order[i]); | |
171 | |
172 if (!profile->IsOffTheRecord()) { | |
173 // We only register preferences on normal profiles because the incognito | |
174 // profile shares the pref service with the normal one. | |
175 factory->RegisterUserPrefsOnProfile(profile); | |
176 } | |
177 | |
178 if (is_testing_profile && factory->ServiceIsNULLWhileTesting()) { | |
179 factory->SetEmptyTestingFactory(profile); | |
180 } else if (factory->ServiceIsCreatedWithProfile()) { | |
181 // Create the service. | |
182 factory->CreateServiceNow(profile); | |
183 } | |
184 } | |
185 } | |
186 | |
187 void ProfileDependencyManager::DestroyProfileServices(Profile* profile) { | |
188 std::vector<DependencyNode*> destruction_order; | |
189 if (!dependency_graph_.GetDestructionOrder(&destruction_order)) { | |
190 NOTREACHED(); | |
191 } | |
192 | |
193 #ifndef NDEBUG | |
194 DumpProfileDependencies(profile); | |
195 #endif | |
196 | |
197 for (size_t i = 0; i < destruction_order.size(); i++) { | |
198 ProfileKeyedBaseFactory* factory = | |
199 static_cast<ProfileKeyedBaseFactory*>(destruction_order[i]); | |
200 factory->ProfileShutdown(profile); | |
201 } | |
202 | |
203 #ifndef NDEBUG | |
204 // The profile is now dead to the rest of the program. | |
205 dead_profile_pointers_.insert(profile); | |
206 #endif | |
207 | |
208 for (size_t i = 0; i < destruction_order.size(); i++) { | |
209 ProfileKeyedBaseFactory* factory = | |
210 static_cast<ProfileKeyedBaseFactory*>(destruction_order[i]); | |
211 factory->ProfileDestroyed(profile); | |
212 } | |
213 } | |
214 | |
215 #ifndef NDEBUG | |
216 void ProfileDependencyManager::AssertProfileWasntDestroyed(Profile* profile) { | |
217 if (dead_profile_pointers_.find(profile) != dead_profile_pointers_.end()) { | |
218 NOTREACHED() << "Attempted to access a Profile that was ShutDown(). This " | |
219 << "is most likely a heap smasher in progress. After " | |
220 << "ProfileKeyedService::Shutdown() completes, your service " | |
221 << "MUST NOT refer to depended Profile services again."; | |
222 } | |
223 } | |
224 #endif | |
225 | |
226 // static | |
227 ProfileDependencyManager* ProfileDependencyManager::GetInstance() { | |
228 return Singleton<ProfileDependencyManager>::get(); | |
229 } | |
230 | |
231 ProfileDependencyManager::ProfileDependencyManager() : built_factories_(false) { | |
232 } | |
233 | |
234 ProfileDependencyManager::~ProfileDependencyManager() {} | |
235 | |
236 // This method gets the instance of each ServiceFactory. We do this so that | 133 // This method gets the instance of each ServiceFactory. We do this so that |
237 // each ServiceFactory initializes itself and registers its dependencies with | 134 // each ServiceFactory initializes itself and registers its dependencies with |
238 // the global PreferenceDependencyManager. We need to have a complete | 135 // the global PreferenceDependencyManager. We need to have a complete |
239 // dependency graph when we create a profile so we can dispatch the profile | 136 // dependency graph when we create a profile so we can dispatch the profile |
240 // creation message to the services that want to create their services at | 137 // creation message to the services that want to create their services at |
241 // profile creation time. | 138 // profile creation time. |
242 // | 139 // |
243 // TODO(erg): This needs to be something else. I don't think putting every | 140 // TODO(erg): This needs to be something else. I don't think putting every |
244 // FooServiceFactory here will scale or is desirable long term. | 141 // FooServiceFactory here will scale or is desirable long term. |
245 void ProfileDependencyManager::AssertFactoriesBuilt() { | 142 // |
246 if (built_factories_) | 143 // static |
247 return; | 144 void |
248 | 145 ChromeBrowserMainExtraPartsProfiles::EnsureProfileKeyedServiceFactoriesBuilt() { |
249 AboutSigninInternalsFactory::GetInstance(); | 146 AboutSigninInternalsFactory::GetInstance(); |
250 | 147 |
251 #if defined(ENABLE_BACKGROUND) | 148 #if defined(ENABLE_BACKGROUND) |
252 BackgroundContentsServiceFactory::GetInstance(); | 149 BackgroundContentsServiceFactory::GetInstance(); |
253 #endif | 150 #endif |
254 BookmarkModelFactory::GetInstance(); | 151 BookmarkModelFactory::GetInstance(); |
255 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 152 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) |
256 captive_portal::CaptivePortalServiceFactory::GetInstance(); | 153 captive_portal::CaptivePortalServiceFactory::GetInstance(); |
257 #endif | 154 #endif |
258 ChromeGeolocationPermissionContextFactory::GetInstance(); | 155 ChromeGeolocationPermissionContextFactory::GetInstance(); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 TemplateURLServiceFactory::GetInstance(); | 268 TemplateURLServiceFactory::GetInstance(); |
372 #if defined(ENABLE_THEMES) | 269 #if defined(ENABLE_THEMES) |
373 ThemeServiceFactory::GetInstance(); | 270 ThemeServiceFactory::GetInstance(); |
374 #endif | 271 #endif |
375 TokenCacheServiceFactory::GetInstance(); | 272 TokenCacheServiceFactory::GetInstance(); |
376 TokenServiceFactory::GetInstance(); | 273 TokenServiceFactory::GetInstance(); |
377 #if !defined(OS_ANDROID) | 274 #if !defined(OS_ANDROID) |
378 UserStyleSheetWatcherFactory::GetInstance(); | 275 UserStyleSheetWatcherFactory::GetInstance(); |
379 #endif | 276 #endif |
380 WebDataServiceFactory::GetInstance(); | 277 WebDataServiceFactory::GetInstance(); |
381 | |
382 built_factories_ = true; | |
383 } | 278 } |
384 | 279 |
385 #ifndef NDEBUG | 280 void ChromeBrowserMainExtraPartsProfiles::PreProfileInit() { |
386 namespace { | 281 EnsureProfileKeyedServiceFactoriesBuilt(); |
387 | |
388 std::string ProfileKeyedBaseFactoryGetNodeName(DependencyNode* node) { | |
389 return static_cast<ProfileKeyedBaseFactory*>(node)->name(); | |
390 } | 282 } |
391 | |
392 } // namespace | |
393 | |
394 void ProfileDependencyManager::DumpProfileDependencies(Profile* profile) { | |
395 // Whenever we try to build a destruction ordering, we should also dump a | |
396 // dependency graph to "/path/to/profile/profile-dependencies.dot". | |
397 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
398 switches::kDumpProfileDependencyGraph)) { | |
399 base::FilePath dot_file = | |
400 profile->GetPath().AppendASCII("profile-dependencies.dot"); | |
401 std::string contents = dependency_graph_.DumpAsGraphviz( | |
402 "Profile", base::Bind(&ProfileKeyedBaseFactoryGetNodeName)); | |
403 file_util::WriteFile(dot_file, contents.c_str(), contents.size()); | |
404 } | |
405 } | |
406 #endif // NDEBUG | |
OLD | NEW |