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