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/refcounted_browser_context_keyed_service_factory.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "components/keyed_service/content/refcounted_browser_context_keyed_service.h"
10 #include "components/keyed_service/core/keyed_service.h"
11 #include "content/public/browser/browser_context.h"
13 void RefcountedBrowserContextKeyedServiceFactory::SetTestingFactory(
14 content::BrowserContext
* context
,
15 TestingFactoryFunction testing_factory
) {
16 // Destroying the context may cause us to lose data about whether |context|
17 // has our preferences registered on it (since the context object itself
18 // isn't dead). See if we need to readd it once we've gone through normal
20 bool add_context
= ArePreferencesSetOn(context
);
22 // We have to go through the shutdown and destroy mechanisms because there
23 // are unit tests that create a service on a context and then change the
24 // testing service mid-test.
25 BrowserContextShutdown(context
);
26 BrowserContextDestroyed(context
);
29 MarkPreferencesSetOn(context
);
31 testing_factories_
[context
] = testing_factory
;
34 scoped_refptr
<RefcountedBrowserContextKeyedService
>
35 RefcountedBrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
36 content::BrowserContext
* context
,
37 TestingFactoryFunction testing_factory
) {
38 DCHECK(testing_factory
);
39 SetTestingFactory(context
, testing_factory
);
40 return GetServiceForBrowserContext(context
, true);
43 RefcountedBrowserContextKeyedServiceFactory::
44 RefcountedBrowserContextKeyedServiceFactory(
46 BrowserContextDependencyManager
* manager
)
47 : BrowserContextKeyedBaseFactory(name
, manager
) {}
49 RefcountedBrowserContextKeyedServiceFactory::
50 ~RefcountedBrowserContextKeyedServiceFactory() {
51 DCHECK(mapping_
.empty());
54 scoped_refptr
<RefcountedBrowserContextKeyedService
>
55 RefcountedBrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
56 content::BrowserContext
* context
,
58 context
= GetBrowserContextToUse(context
);
62 // NOTE: If you modify any of the logic below, make sure to update the
63 // non-refcounted version in context_keyed_service_factory.cc!
64 RefCountedStorage::const_iterator it
= mapping_
.find(context
);
65 if (it
!= mapping_
.end())
70 return NULL
; // And we're forbidden from creating one.
73 // Check to see if we have a per-BrowserContext testing factory that we should
74 // use instead of default behavior.
75 scoped_refptr
<RefcountedBrowserContextKeyedService
> service
;
76 BrowserContextOverriddenTestingFunctions::const_iterator jt
=
77 testing_factories_
.find(context
);
78 if (jt
!= testing_factories_
.end()) {
80 if (!context
->IsOffTheRecord())
81 RegisterUserPrefsOnBrowserContextForTest(context
);
82 service
= jt
->second(context
);
85 service
= BuildServiceInstanceFor(context
);
88 Associate(context
, service
);
92 void RefcountedBrowserContextKeyedServiceFactory::Associate(
93 content::BrowserContext
* context
,
94 const scoped_refptr
<RefcountedBrowserContextKeyedService
>& service
) {
95 DCHECK(!ContainsKey(mapping_
, context
));
96 mapping_
.insert(std::make_pair(context
, service
));
99 void RefcountedBrowserContextKeyedServiceFactory::BrowserContextShutdown(
100 content::BrowserContext
* context
) {
101 RefCountedStorage::iterator it
= mapping_
.find(context
);
102 if (it
!= mapping_
.end() && it
->second
.get())
103 it
->second
->ShutdownOnUIThread();
106 void RefcountedBrowserContextKeyedServiceFactory::BrowserContextDestroyed(
107 content::BrowserContext
* context
) {
108 // We "merely" drop our reference to the service. Hopefully this will cause
109 // the service to be destroyed. If not, oh well.
110 mapping_
.erase(context
);
112 // For unit tests, we also remove the factory function both so we don't
113 // maintain a big map of dead pointers, but also since we may have a second
114 // object that lives at the same address (see other comments about unit tests
116 testing_factories_
.erase(context
);
118 BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context
);
121 void RefcountedBrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
122 content::BrowserContext
* context
) {
123 SetTestingFactory(context
, NULL
);
126 bool RefcountedBrowserContextKeyedServiceFactory::HasTestingFactory(
127 content::BrowserContext
* context
) {
128 return testing_factories_
.find(context
) != testing_factories_
.end();
131 void RefcountedBrowserContextKeyedServiceFactory::CreateServiceNow(
132 content::BrowserContext
* context
) {
133 GetServiceForBrowserContext(context
, true);