browser_context_keyed_service_factory.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 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. 4 5#include "components/keyed_service/content/browser_context_keyed_service_factory.h" 6 7#include <map> 8 9#include "base/logging.h" 10#include "base/stl_util.h" 11#include "components/keyed_service/content/browser_context_dependency_manager.h" 12#include "components/keyed_service/core/keyed_service.h" 13#include "content/public/browser/browser_context.h" 14 15void BrowserContextKeyedServiceFactory::SetTestingFactory( 16 content::BrowserContext* context, 17 TestingFactoryFunction testing_factory) { 18 // Destroying the context may cause us to lose data about whether |context| 19 // has our preferences registered on it (since the context object itself 20 // isn't dead). See if we need to readd it once we've gone through normal 21 // destruction. 22 bool add_context = ArePreferencesSetOn(context); 23 24#ifndef NDEBUG 25 // Ensure that |context| is not marked as stale (e.g., due to it aliasing an 26 // instance that was destroyed in an earlier test) in order to avoid accesses 27 // to |context| in |BrowserContextShutdown| from causing 28 // |AssertBrowserContextWasntDestroyed| to raise an error. 29 dependency_manager_->MarkBrowserContextLiveForTesting(context); 30#endif 31 32 // We have to go through the shutdown and destroy mechanisms because there 33 // are unit tests that create a service on a context and then change the 34 // testing service mid-test. 35 BrowserContextShutdown(context); 36 BrowserContextDestroyed(context); 37 38 if (add_context) 39 MarkPreferencesSetOn(context); 40 41 testing_factories_[context] = testing_factory; 42} 43 44KeyedService* BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse( 45 content::BrowserContext* context, 46 TestingFactoryFunction testing_factory) { 47 DCHECK(testing_factory); 48 SetTestingFactory(context, testing_factory); 49 return GetServiceForBrowserContext(context, true); 50} 51 52BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory( 53 const char* name, 54 BrowserContextDependencyManager* manager) 55 : BrowserContextKeyedBaseFactory(name, manager) {} 56 57BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() { 58 DCHECK(mapping_.empty()); 59} 60 61KeyedService* BrowserContextKeyedServiceFactory::GetServiceForBrowserContext( 62 content::BrowserContext* context, 63 bool create) { 64 context = GetBrowserContextToUse(context); 65 if (!context) 66 return NULL; 67 68 // NOTE: If you modify any of the logic below, make sure to update the 69 // refcounted version in refcounted_context_keyed_service_factory.cc! 70 BrowserContextKeyedServices::const_iterator it = mapping_.find(context); 71 if (it != mapping_.end()) 72 return it->second; 73 74 // Object not found. 75 if (!create) 76 return NULL; // And we're forbidden from creating one. 77 78 // Create new object. 79 // Check to see if we have a per-BrowserContext testing factory that we should 80 // use instead of default behavior. 81 KeyedService* service = NULL; 82 BrowserContextOverriddenTestingFunctions::const_iterator jt = 83 testing_factories_.find(context); 84 if (jt != testing_factories_.end()) { 85 if (jt->second) { 86 if (!context->IsOffTheRecord()) 87 RegisterUserPrefsOnBrowserContextForTest(context); 88 service = jt->second(context); 89 } 90 } else { 91 service = BuildServiceInstanceFor(context); 92 } 93 94 Associate(context, service); 95 return service; 96} 97 98void BrowserContextKeyedServiceFactory::Associate( 99 content::BrowserContext* context, 100 KeyedService* service) { 101 DCHECK(!ContainsKey(mapping_, context)); 102 mapping_.insert(std::make_pair(context, service)); 103} 104 105void BrowserContextKeyedServiceFactory::Disassociate( 106 content::BrowserContext* context) { 107 BrowserContextKeyedServices::iterator it = mapping_.find(context); 108 if (it != mapping_.end()) { 109 delete it->second; 110 mapping_.erase(it); 111 } 112} 113 114void BrowserContextKeyedServiceFactory::BrowserContextShutdown( 115 content::BrowserContext* context) { 116 BrowserContextKeyedServices::iterator it = mapping_.find(context); 117 if (it != mapping_.end() && it->second) 118 it->second->Shutdown(); 119} 120 121void BrowserContextKeyedServiceFactory::BrowserContextDestroyed( 122 content::BrowserContext* context) { 123 Disassociate(context); 124 125 // For unit tests, we also remove the factory function both so we don't 126 // maintain a big map of dead pointers, but also since we may have a second 127 // object that lives at the same address (see other comments about unit tests 128 // in this file). 129 testing_factories_.erase(context); 130 131 BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context); 132} 133 134void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory( 135 content::BrowserContext* context) { 136 SetTestingFactory(context, NULL); 137} 138 139void BrowserContextKeyedServiceFactory::CreateServiceNow( 140 content::BrowserContext* context) { 141 GetServiceForBrowserContext(context, true); 142} 143