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 "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
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"
15 void BrowserContextKeyedServiceFactory::SetTestingFactory(
16 content::BrowserContext* context, TestingFactoryFunction testing_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
21 bool add_context = ArePreferencesSetOn(context);
24 // Ensure that |context| is not marked as stale (e.g., due to it aliasing an
25 // instance that was destroyed in an earlier test) in order to avoid accesses
26 // to |context| in |BrowserContextShutdown| from causing
27 // |AssertBrowserContextWasntDestroyed| to raise an error.
28 dependency_manager_->MarkBrowserContextLiveForTesting(context);
31 // We have to go through the shutdown and destroy mechanisms because there
32 // are unit tests that create a service on a context and then change the
33 // testing service mid-test.
34 BrowserContextShutdown(context);
35 BrowserContextDestroyed(context);
38 MarkPreferencesSetOn(context);
40 testing_factories_[context] = testing_factory;
43 BrowserContextKeyedService*
44 BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
45 content::BrowserContext* context,
46 TestingFactoryFunction testing_factory) {
47 DCHECK(testing_factory);
48 SetTestingFactory(context, testing_factory);
49 return GetServiceForBrowserContext(context, true);
52 BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory(
53 const char* name, BrowserContextDependencyManager* manager)
54 : BrowserContextKeyedBaseFactory(name, manager) {
57 BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
58 DCHECK(mapping_.empty());
61 BrowserContextKeyedService*
62 BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
63 content::BrowserContext* context,
65 context = GetBrowserContextToUse(context);
69 // NOTE: If you modify any of the logic below, make sure to update the
70 // refcounted version in refcounted_context_keyed_service_factory.cc!
71 BrowserContextKeyedServices::const_iterator it = mapping_.find(context);
72 if (it != mapping_.end())
77 return NULL; // And we're forbidden from creating one.
80 // Check to see if we have a per-BrowserContext testing factory that we should
81 // use instead of default behavior.
82 BrowserContextKeyedService* service = NULL;
83 BrowserContextOverriddenTestingFunctions::const_iterator jt =
84 testing_factories_.find(context);
85 if (jt != testing_factories_.end()) {
87 if (!context->IsOffTheRecord())
88 RegisterUserPrefsOnBrowserContextForTest(context);
89 service = jt->second(context);
92 service = BuildServiceInstanceFor(context);
95 Associate(context, service);
99 void BrowserContextKeyedServiceFactory::Associate(
100 content::BrowserContext* context,
101 BrowserContextKeyedService* service) {
102 DCHECK(!ContainsKey(mapping_, context));
103 mapping_.insert(std::make_pair(context, service));
106 void BrowserContextKeyedServiceFactory::Disassociate(
107 content::BrowserContext* context) {
108 BrowserContextKeyedServices::iterator it = mapping_.find(context);
109 if (it != mapping_.end()) {
115 void BrowserContextKeyedServiceFactory::BrowserContextShutdown(
116 content::BrowserContext* context) {
117 BrowserContextKeyedServices::iterator it = mapping_.find(context);
118 if (it != mapping_.end() && it->second)
119 it->second->Shutdown();
122 void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
123 content::BrowserContext* context) {
124 Disassociate(context);
126 // For unit tests, we also remove the factory function both so we don't
127 // maintain a big map of dead pointers, but also since we may have a second
128 // object that lives at the same address (see other comments about unit tests
130 testing_factories_.erase(context);
132 BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context);
135 void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
136 content::BrowserContext* context) {
137 SetTestingFactory(context, NULL);
140 void BrowserContextKeyedServiceFactory::CreateServiceNow(
141 content::BrowserContext* context) {
142 GetServiceForBrowserContext(context, true);