browser_context_dependency_manager.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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) 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<DependencyNode*> construction_order; 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!dependency_graph_.GetConstructionOrder(&construction_order)) { 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED(); 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DumpBrowserContextDependencies(context); 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < construction_order.size(); i++) { 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* factory = 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<BrowserContextKeyedBaseFactory*>(construction_order[i]); 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_testing_context && factory->ServiceIsNULLWhileTesting()) { 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->SetEmptyTestingFactory(context); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (factory->ServiceIsCreatedWithBrowserContext()) { 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create the service. 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->CreateServiceNow(context); 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::DestroyBrowserContextServices( 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<DependencyNode*> destruction_order; 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!dependency_graph_.GetDestructionOrder(&destruction_order)) { 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED(); 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DumpBrowserContextDependencies(context); 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < destruction_order.size(); i++) { 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* factory = 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]); 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->BrowserContextShutdown(context); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The context is now dead to the rest of the program. 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dead_context_pointers_.insert(context); 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < destruction_order.size(); i++) { 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory* factory = 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]); 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) factory->BrowserContextDestroyed(context); 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::AssertBrowserContextWasntDestroyed( 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) { 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED() << "Attempted to access a BrowserContext that was ShutDown(). " 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << "This is most likely a heap smasher in progress. After " 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "KeyedService::Shutdown() completes, your " 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << "service MUST NOT refer to depended BrowserContext " 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << "services again."; 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserContextDependencyManager::MarkBrowserContextLiveForTesting( 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::BrowserContext* context) { 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dead_context_pointers_.erase(context); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextDependencyManager* 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextDependencyManager::GetInstance() { 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Singleton<BrowserContextDependencyManager>::get(); 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextDependencyManager::BrowserContextDependencyManager() {} 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextDependencyManager::~BrowserContextDependencyManager() {} 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef NDEBUG 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string BrowserContextKeyedBaseFactoryGetNodeName(DependencyNode* node) { 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return static_cast<BrowserContextKeyedBaseFactory*>(node)->name(); 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextDependencyManager::DumpBrowserContextDependencies( 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Whenever we try to build a destruction ordering, we should also dump a 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // dependency graph to "/path/to/context/context-dependencies.dot". 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) kDumpBrowserContextDependencyGraphFlag)) { 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath dot_file = 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) context->GetPath().AppendASCII("browser-context-dependencies.dot"); 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string contents = dependency_graph_.DumpAsGraphviz( 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "BrowserContext", 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&BrowserContextKeyedBaseFactoryGetNodeName)); 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile(dot_file, contents.c_str(), contents.size()); 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // NDEBUG 182