browser_context_dependency_manager.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/content/browser_context_dependency_manager.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <algorithm> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <deque> 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <iterator> 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/debug/trace_event.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/content/browser_context_keyed_base_factory.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/browser_context.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/command_line.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/file_util.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Dumps dependency information about our browser context keyed services 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// into a dot file in the browser context directory. 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kDumpBrowserContextDependencyGraphFlag[] = 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "dump-browser-context-graph"; 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif // NDEBUG 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::AddComponent( 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* component) { 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dependency_graph_.AddNode(component); 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::RemoveComponent( 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* component) { 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dependency_graph_.RemoveNode(component); 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::AddEdge( 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* depended, 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* dependee) { 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dependency_graph_.AddEdge(depended, dependee); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void BrowserContextDependencyManager::RegisterProfilePrefsForServices( 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const content::BrowserContext* context, 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) user_prefs::PrefRegistrySyncable* pref_registry) { 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<DependencyNode*> construction_order; 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!dependency_graph_.GetConstructionOrder(&construction_order)) { 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (std::vector<DependencyNode*>::const_iterator it = 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) construction_order.begin(); 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it != construction_order.end(); 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++it) { 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserContextKeyedBaseFactory* factory = 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<BrowserContextKeyedBaseFactory*>(*it); 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) factory->RegisterProfilePrefsIfNecessaryForContext(context, pref_registry); 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::CreateBrowserContextServices( 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::BrowserContext* context) { 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DoCreateBrowserContextServices(context, false); 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void BrowserContextDependencyManager::CreateBrowserContextServicesForTest( 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::BrowserContext* context) { 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DoCreateBrowserContextServices(context, true); 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void BrowserContextDependencyManager::DoCreateBrowserContextServices( 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::BrowserContext* context, 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_testing_context) { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TRACE_EVENT0( 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "browser", 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "BrowserContextDependencyManager::DoCreateBrowserContextServices") 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MarkBrowserContextLiveForTesting(context); 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch will_create_browser_context_services_callbacks_.Notify(context); 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<DependencyNode*> construction_order; 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!dependency_graph_.GetConstructionOrder(&construction_order)) { 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED(); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DumpBrowserContextDependencies(context); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < construction_order.size(); i++) { 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* factory = 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<BrowserContextKeyedBaseFactory*>(construction_order[i]); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_testing_context && factory->ServiceIsNULLWhileTesting()) { 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->SetEmptyTestingFactory(context); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (factory->ServiceIsCreatedWithBrowserContext()) { 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create the service. 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->CreateServiceNow(context); 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::DestroyBrowserContextServices( 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<DependencyNode*> destruction_order; 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!dependency_graph_.GetDestructionOrder(&destruction_order)) { 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED(); 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DumpBrowserContextDependencies(context); 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < destruction_order.size(); i++) { 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* factory = 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]); 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->BrowserContextShutdown(context); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The context is now dead to the rest of the program. 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dead_context_pointers_.insert(context); 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < destruction_order.size(); i++) { 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* factory = 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]); 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->BrowserContextDestroyed(context); 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochscoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription> 1330529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochBrowserContextDependencyManager:: 1340529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochRegisterWillCreateBrowserContextServicesCallbackForTesting( 1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const base::Callback<void(content::BrowserContext*)>& callback) { 1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return will_create_browser_context_services_callbacks_.Add(callback); 1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::AssertBrowserContextWasntDestroyed( 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) { 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED() << "Attempted to access a BrowserContext that was ShutDown(). " 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << "This is most likely a heap smasher in progress. After " 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "KeyedService::Shutdown() completes, your " 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << "service MUST NOT refer to depended BrowserContext " 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << "services again."; 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserContextDependencyManager::MarkBrowserContextLiveForTesting( 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::BrowserContext* context) { 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dead_context_pointers_.erase(context); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextDependencyManager* 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextDependencyManager::GetInstance() { 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Singleton<BrowserContextDependencyManager>::get(); 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextDependencyManager::BrowserContextDependencyManager() {} 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextDependencyManager::~BrowserContextDependencyManager() {} 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string BrowserContextKeyedBaseFactoryGetNodeName(DependencyNode* node) { 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return static_cast<BrowserContextKeyedBaseFactory*>(node)->name(); 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::DumpBrowserContextDependencies( 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Whenever we try to build a destruction ordering, we should also dump a 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // dependency graph to "/path/to/context/context-dependencies.dot". 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kDumpBrowserContextDependencyGraphFlag)) { 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath dot_file = 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) context->GetPath().AppendASCII("browser-context-dependencies.dot"); 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string contents = dependency_graph_.DumpAsGraphviz( 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "BrowserContext", 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&BrowserContextKeyedBaseFactoryGetNodeName)); 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile(dot_file, contents.c_str(), contents.size()); 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // NDEBUG 191