Revert 168224 - Update V8 to version 3.15.4.
[chromium-blink-merge.git] / chrome / browser / profiles / profile_dependency_manager.cc
blob66744980be79621af09f3e511b42941e3b4a6e12
1 // Copyright (c) 2012 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 "chrome/browser/profiles/profile_dependency_manager.h"
7 #include <algorithm>
8 #include <deque>
9 #include <iterator>
11 #include "chrome/browser/autofill/personal_data_manager_factory.h"
12 #include "chrome/browser/background/background_contents_service_factory.h"
13 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
14 #include "chrome/browser/content_settings/cookie_settings.h"
15 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
16 #include "chrome/browser/download/download_service_factory.h"
17 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_factory.h"
18 #include "chrome/browser/extensions/api/commands/command_service_factory.h"
19 #include "chrome/browser/extensions/api/discovery/suggested_links_registry_factory.h"
20 #include "chrome/browser/extensions/api/processes/processes_api_factory.h"
21 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry_factory.h"
22 #include "chrome/browser/extensions/app_restore_service_factory.h"
23 #include "chrome/browser/extensions/extension_system_factory.h"
24 #include "chrome/browser/favicon/favicon_service_factory.h"
25 #include "chrome/browser/google/google_url_tracker_factory.h"
26 #include "chrome/browser/history/history_service_factory.h"
27 #include "chrome/browser/history/shortcuts_backend_factory.h"
28 #include "chrome/browser/intents/web_intents_registry_factory.h"
29 #include "chrome/browser/media_gallery/media_galleries_preferences_factory.h"
30 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
31 #include "chrome/browser/password_manager/password_store_factory.h"
32 #include "chrome/browser/plugins/plugin_prefs_factory.h"
33 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
34 #include "chrome/browser/predictors/predictor_database_factory.h"
35 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h"
36 #include "chrome/browser/prerender/prerender_link_manager_factory.h"
37 #include "chrome/browser/prerender/prerender_manager_factory.h"
38 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
39 #include "chrome/browser/profiles/profile.h"
40 #include "chrome/browser/profiles/profile_keyed_service.h"
41 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
42 #include "chrome/browser/protector/protector_service_factory.h"
43 #include "chrome/browser/search_engines/template_url_fetcher_factory.h"
44 #include "chrome/browser/search_engines/template_url_service_factory.h"
45 #include "chrome/browser/sessions/session_service_factory.h"
46 #include "chrome/browser/sessions/tab_restore_service_factory.h"
47 #include "chrome/browser/signin/signin_manager_factory.h"
48 #include "chrome/browser/signin/token_service_factory.h"
49 #include "chrome/browser/speech/chrome_speech_recognition_preferences.h"
50 #include "chrome/browser/speech/speech_input_extension_manager.h"
51 #include "chrome/browser/spellchecker/spellcheck_factory.h"
52 #if defined(OS_WIN)
53 #include "chrome/browser/sync/credential_cache_service_factory_win.h"
54 #endif // OS_WIN
55 #include "chrome/browser/sync/profile_sync_service_factory.h"
56 #include "chrome/browser/themes/theme_service_factory.h"
57 #include "chrome/browser/thumbnails/thumbnail_service_factory.h"
58 #include "chrome/browser/ui/find_bar/find_bar_state_factory.h"
59 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
60 #include "chrome/browser/ui/tabs/pinned_tab_service_factory.h"
61 #include "chrome/browser/ui/webui/chrome_url_data_manager_factory.h"
62 #include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
63 #include "chrome/browser/user_style_sheet_watcher_factory.h"
64 #include "chrome/browser/visitedlink/visitedlink_master_factory.h"
65 #include "chrome/browser/webdata/web_data_service_factory.h"
67 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
68 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
69 #endif
71 #if defined(ENABLE_CONFIGURATION_POLICY)
72 #include "chrome/browser/policy/user_policy_signin_service_factory.h"
73 #endif
75 #if defined(USE_AURA)
76 #include "chrome/browser/ui/gesture_prefs_observer_factory_aura.h"
77 #endif
79 #ifndef NDEBUG
80 #include "base/command_line.h"
81 #include "base/file_util.h"
82 #include "chrome/common/chrome_switches.h"
83 #endif
85 class Profile;
87 void ProfileDependencyManager::AddComponent(
88 ProfileKeyedBaseFactory* component) {
89 all_components_.push_back(component);
90 destruction_order_.clear();
93 void ProfileDependencyManager::RemoveComponent(
94 ProfileKeyedBaseFactory* component) {
95 all_components_.erase(std::remove(all_components_.begin(),
96 all_components_.end(),
97 component),
98 all_components_.end());
100 // Remove all dependency edges that contain this component.
101 EdgeMap::iterator it = edges_.begin();
102 while (it != edges_.end()) {
103 EdgeMap::iterator temp = it;
104 ++it;
106 if (temp->first == component || temp->second == component)
107 edges_.erase(temp);
110 destruction_order_.clear();
113 void ProfileDependencyManager::AddEdge(ProfileKeyedBaseFactory* depended,
114 ProfileKeyedBaseFactory* dependee) {
115 edges_.insert(std::make_pair(depended, dependee));
116 destruction_order_.clear();
119 void ProfileDependencyManager::CreateProfileServices(Profile* profile,
120 bool is_testing_profile) {
121 #ifndef NDEBUG
122 // Unmark |profile| as dead. This exists because of unit tests, which will
123 // often have similar stack structures. 0xWhatever might be created, go out
124 // of scope, and then a new Profile object might be created at 0xWhatever.
125 dead_profile_pointers_.erase(profile);
126 #endif
128 AssertFactoriesBuilt();
130 if (destruction_order_.empty())
131 BuildDestructionOrder(profile);
133 // Iterate in reverse destruction order for creation.
134 for (std::vector<ProfileKeyedBaseFactory*>::reverse_iterator rit =
135 destruction_order_.rbegin(); rit != destruction_order_.rend();
136 ++rit) {
137 if (!profile->IsOffTheRecord()) {
138 // We only register preferences on normal profiles because the incognito
139 // profile shares the pref service with the normal one.
140 (*rit)->RegisterUserPrefsOnProfile(profile);
143 if (is_testing_profile && (*rit)->ServiceIsNULLWhileTesting()) {
144 (*rit)->SetEmptyTestingFactory(profile);
145 } else if ((*rit)->ServiceIsCreatedWithProfile()) {
146 // Create the service.
147 (*rit)->CreateServiceNow(profile);
152 void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
153 if (destruction_order_.empty())
154 BuildDestructionOrder(profile);
156 for (std::vector<ProfileKeyedBaseFactory*>::const_iterator it =
157 destruction_order_.begin(); it != destruction_order_.end(); ++it) {
158 (*it)->ProfileShutdown(profile);
161 #ifndef NDEBUG
162 // The profile is now dead to the rest of the program.
163 dead_profile_pointers_.insert(profile);
164 #endif
166 for (std::vector<ProfileKeyedBaseFactory*>::const_iterator it =
167 destruction_order_.begin(); it != destruction_order_.end(); ++it) {
168 (*it)->ProfileDestroyed(profile);
172 #ifndef NDEBUG
173 void ProfileDependencyManager::AssertProfileWasntDestroyed(Profile* profile) {
174 if (dead_profile_pointers_.find(profile) != dead_profile_pointers_.end()) {
175 NOTREACHED() << "Attempted to access a Profile that was ShutDown(). This "
176 << "is most likely a heap smasher in progress. After "
177 << "ProfileKeyedService::Shutdown() completes, your service "
178 << "MUST NOT refer to depended Profile services again.";
181 #endif
183 // static
184 ProfileDependencyManager* ProfileDependencyManager::GetInstance() {
185 return Singleton<ProfileDependencyManager>::get();
188 ProfileDependencyManager::ProfileDependencyManager()
189 : built_factories_(false) {
192 ProfileDependencyManager::~ProfileDependencyManager() {}
194 // This method gets the instance of each ServiceFactory. We do this so that
195 // each ServiceFactory initializes iteslf and registers its dependencies with
196 // the global PreferenceDependencyManager. We need to have a complete
197 // dependency graph when we create a profile so we can dispatch the profile
198 // creation message to the services that want to create their services at
199 // profile creation time.
201 // TODO(erg): This needs to be something else. I don't think putting every
202 // FooServiceFactory here will scale or is desireable long term.
203 void ProfileDependencyManager::AssertFactoriesBuilt() {
204 if (built_factories_)
205 return;
207 #if defined(ENABLE_BACKGROUND)
208 BackgroundContentsServiceFactory::GetInstance();
209 #endif
210 BookmarkModelFactory::GetInstance();
211 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
212 captive_portal::CaptivePortalServiceFactory::GetInstance();
213 #endif
214 ChromeURLDataManagerFactory::GetInstance();
215 #if defined(ENABLE_PRINTING)
216 CloudPrintProxyServiceFactory::GetInstance();
217 #endif
218 CookieSettings::Factory::GetInstance();
219 #if defined(ENABLE_NOTIFICATIONS)
220 DesktopNotificationServiceFactory::GetInstance();
221 #endif
222 DownloadServiceFactory::GetInstance();
223 #if defined(ENABLE_EXTENSIONS)
224 extensions::AppRestoreServiceFactory::GetInstance();
225 extensions::BluetoothAPIFactory::GetInstance();
226 extensions::CommandServiceFactory::GetInstance();
227 extensions::SuggestedLinksRegistryFactory::GetInstance();
228 extensions::ExtensionSystemFactory::GetInstance();
229 extensions::ProcessesAPIFactory::GetInstance();
230 extensions::TabCaptureRegistryFactory::GetInstance();
231 #endif
232 FaviconServiceFactory::GetInstance();
233 FindBarStateFactory::GetInstance();
234 #if defined(USE_AURA)
235 GesturePrefsObserverFactoryAura::GetInstance();
236 #endif
237 GlobalErrorServiceFactory::GetInstance();
238 GoogleURLTrackerFactory::GetInstance();
239 HistoryServiceFactory::GetInstance();
240 MediaGalleriesPreferencesFactory::GetInstance();
241 NTPResourceCacheFactory::GetInstance();
242 PasswordStoreFactory::GetInstance();
243 PersonalDataManagerFactory::GetInstance();
244 #if !defined(OS_ANDROID)
245 PinnedTabServiceFactory::GetInstance();
246 #endif
247 PluginPrefsFactory::GetInstance();
248 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS)
249 // Not used on chromeos because signin happens before the profile is loaded.
250 policy::UserPolicySigninServiceFactory::GetInstance();
251 #endif
252 predictors::AutocompleteActionPredictorFactory::GetInstance();
253 predictors::PredictorDatabaseFactory::GetInstance();
254 predictors::ResourcePrefetchPredictorFactory::GetInstance();
255 prerender::PrerenderManagerFactory::GetInstance();
256 prerender::PrerenderLinkManagerFactory::GetInstance();
257 ProfileSyncServiceFactory::GetInstance();
258 ProtocolHandlerRegistryFactory::GetInstance();
259 #if defined(ENABLE_PROTECTOR_SERVICE)
260 protector::ProtectorServiceFactory::GetInstance();
261 #endif
262 #if defined(ENABLE_SESSION_SERVICE)
263 SessionServiceFactory::GetInstance();
264 #endif
265 ShortcutsBackendFactory::GetInstance();
266 ThumbnailServiceFactory::GetInstance();
267 SigninManagerFactory::GetInstance();
268 #if defined(ENABLE_INPUT_SPEECH)
269 SpeechInputExtensionManager::InitializeFactory();
270 ChromeSpeechRecognitionPreferences::InitializeFactory();
271 #endif
272 SpellcheckServiceFactory::GetInstance();
273 #if defined(OS_WIN)
274 syncer::CredentialCacheServiceFactory::GetInstance();
275 #endif // OS_WIN
276 TabRestoreServiceFactory::GetInstance();
277 TemplateURLFetcherFactory::GetInstance();
278 TemplateURLServiceFactory::GetInstance();
279 #if defined(ENABLE_THEMES)
280 ThemeServiceFactory::GetInstance();
281 #endif
282 TokenServiceFactory::GetInstance();
283 UserStyleSheetWatcherFactory::GetInstance();
284 VisitedLinkMasterFactory::GetInstance();
285 WebDataServiceFactory::GetInstance();
286 #if defined(ENABLE_WEB_INTENTS)
287 WebIntentsRegistryFactory::GetInstance();
288 #endif
290 built_factories_ = true;
293 void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) {
294 #if !defined(NDEBUG)
295 // Whenever we try to build a destruction ordering, we should also dump a
296 // dependency graph to "/path/to/profile/profile-dependencies.dot".
297 if (CommandLine::ForCurrentProcess()->HasSwitch(
298 switches::kDumpProfileDependencyGraph)) {
299 FilePath dot_file =
300 profile->GetPath().AppendASCII("profile-dependencies.dot");
301 std::string contents = DumpGraphvizDependency();
302 file_util::WriteFile(dot_file, contents.c_str(), contents.size());
304 #endif
306 // Step 1: Build a set of nodes with no incoming edges.
307 std::deque<ProfileKeyedBaseFactory*> queue;
308 std::copy(all_components_.begin(),
309 all_components_.end(),
310 std::back_inserter(queue));
312 std::deque<ProfileKeyedBaseFactory*>::iterator queue_end = queue.end();
313 for (EdgeMap::const_iterator it = edges_.begin();
314 it != edges_.end(); ++it) {
315 queue_end = std::remove(queue.begin(), queue_end, it->second);
317 queue.erase(queue_end, queue.end());
319 // Step 2: Do the Kahn topological sort.
320 std::vector<ProfileKeyedBaseFactory*> output;
321 EdgeMap edges(edges_);
322 while (!queue.empty()) {
323 ProfileKeyedBaseFactory* node = queue.front();
324 queue.pop_front();
325 output.push_back(node);
327 std::pair<EdgeMap::iterator, EdgeMap::iterator> range =
328 edges.equal_range(node);
329 EdgeMap::iterator it = range.first;
330 while (it != range.second) {
331 ProfileKeyedBaseFactory* dest = it->second;
332 EdgeMap::iterator temp = it;
333 it++;
334 edges.erase(temp);
336 bool has_incoming_edges = false;
337 for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) {
338 if (jt->second == dest) {
339 has_incoming_edges = true;
340 break;
344 if (!has_incoming_edges)
345 queue.push_back(dest);
349 if (edges.size()) {
350 NOTREACHED() << "Dependency graph has a cycle. We are doomed.";
353 std::reverse(output.begin(), output.end());
354 destruction_order_ = output;
357 #if !defined(NDEBUG)
359 std::string ProfileDependencyManager::DumpGraphvizDependency() {
360 std::string result("digraph {\n");
362 // Make a copy of all components.
363 std::deque<ProfileKeyedBaseFactory*> components;
364 std::copy(all_components_.begin(),
365 all_components_.end(),
366 std::back_inserter(components));
368 // State all dependencies and remove |second| so we don't generate an
369 // implicit dependency on the Profile hard coded node.
370 std::deque<ProfileKeyedBaseFactory*>::iterator components_end =
371 components.end();
372 result.append(" /* Dependencies */\n");
373 for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) {
374 result.append(" ");
375 result.append(it->second->name());
376 result.append(" -> ");
377 result.append(it->first->name());
378 result.append(";\n");
380 components_end = std::remove(components.begin(), components_end,
381 it->second);
383 components.erase(components_end, components.end());
385 // Every node that doesn't depend on anything else will implicitly depend on
386 // the Profile.
387 result.append("\n /* Toplevel attachments */\n");
388 for (std::deque<ProfileKeyedBaseFactory*>::const_iterator it =
389 components.begin(); it != components.end(); ++it) {
390 result.append(" ");
391 result.append((*it)->name());
392 result.append(" -> Profile;\n");
395 result.append("\n /* Toplevel profile */\n");
396 result.append(" Profile [shape=box];\n");
398 result.append("}\n");
399 return result;
402 #endif