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.
5 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
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"
15 void 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
22 bool add_context
= ArePreferencesSetOn(context
);
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
);
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
);
39 MarkPreferencesSetOn(context
);
41 testing_factories_
[context
] = testing_factory
;
44 KeyedService
* 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(
54 BrowserContextDependencyManager
* manager
)
55 : BrowserContextKeyedBaseFactory(name
, manager
) {}
57 BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
58 DCHECK(mapping_
.empty());
61 KeyedService
* BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
62 content::BrowserContext
* context
,
64 context
= GetBrowserContextToUse(context
);
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())
76 return NULL
; // And we're forbidden from creating one.
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()) {
86 if (!context
->IsOffTheRecord())
87 RegisterUserPrefsOnBrowserContextForTest(context
);
88 service
= jt
->second(context
);
91 service
= BuildServiceInstanceFor(context
);
94 Associate(context
, service
);
98 void BrowserContextKeyedServiceFactory::Associate(
99 content::BrowserContext
* context
,
100 KeyedService
* service
) {
101 DCHECK(!ContainsKey(mapping_
, context
));
102 mapping_
.insert(std::make_pair(context
, service
));
105 void BrowserContextKeyedServiceFactory::Disassociate(
106 content::BrowserContext
* context
) {
107 BrowserContextKeyedServices::iterator it
= mapping_
.find(context
);
108 if (it
!= mapping_
.end()) {
114 void BrowserContextKeyedServiceFactory::BrowserContextShutdown(
115 content::BrowserContext
* context
) {
116 BrowserContextKeyedServices::iterator it
= mapping_
.find(context
);
117 if (it
!= mapping_
.end() && it
->second
)
118 it
->second
->Shutdown();
121 void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
122 content::BrowserContext
* context
) {
123 Disassociate(context
);
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
129 testing_factories_
.erase(context
);
131 BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context
);
134 void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
135 content::BrowserContext
* context
) {
136 SetTestingFactory(context
, NULL
);
139 void BrowserContextKeyedServiceFactory::CreateServiceNow(
140 content::BrowserContext
* context
) {
141 GetServiceForBrowserContext(context
, true);