Roll ANGLE cc54ab3..c5b2ba5
[chromium-blink-merge.git] / components / keyed_service / core / keyed_service_factory.cc
blobefc61f904e7b8bc1631e97fff4038afd499c9f1f
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/core/keyed_service_factory.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "base/trace_event/trace_event.h"
10 #include "components/keyed_service/core/dependency_manager.h"
11 #include "components/keyed_service/core/keyed_service.h"
13 KeyedServiceFactory::KeyedServiceFactory(const char* name,
14 DependencyManager* manager)
15 : KeyedServiceBaseFactory(name, manager) {
18 KeyedServiceFactory::~KeyedServiceFactory() {
19 DCHECK(mapping_.empty());
22 void KeyedServiceFactory::SetTestingFactory(
23 base::SupportsUserData* context,
24 TestingFactoryFunction testing_factory) {
25 // Destroying the context may cause us to lose data about whether |context|
26 // has our preferences registered on it (since the context object itself
27 // isn't dead). See if we need to readd it once we've gone through normal
28 // destruction.
29 bool add_context = ArePreferencesSetOn(context);
31 #ifndef NDEBUG
32 // Ensure that |context| is not marked as stale (e.g., due to it aliasing an
33 // instance that was destroyed in an earlier test) in order to avoid accesses
34 // to |context| in |BrowserContextShutdown| from causing
35 // |AssertBrowserContextWasntDestroyed| to raise an error.
36 MarkContextLiveForTesting(context);
37 #endif
39 // We have to go through the shutdown and destroy mechanisms because there
40 // are unit tests that create a service on a context and then change the
41 // testing service mid-test.
42 ContextShutdown(context);
43 ContextDestroyed(context);
45 if (add_context)
46 MarkPreferencesSetOn(context);
48 testing_factories_[context] = testing_factory;
51 KeyedService* KeyedServiceFactory::SetTestingFactoryAndUse(
52 base::SupportsUserData* context,
53 TestingFactoryFunction testing_factory) {
54 DCHECK(testing_factory);
55 SetTestingFactory(context, testing_factory);
56 return GetServiceForContext(context, true);
59 KeyedService* KeyedServiceFactory::GetServiceForContext(
60 base::SupportsUserData* context,
61 bool create) {
62 TRACE_EVENT0("browser,startup", "KeyedServiceFactory::GetServiceForContext");
63 context = GetContextToUse(context);
64 if (!context)
65 return nullptr;
67 // NOTE: If you modify any of the logic below, make sure to update the
68 // refcounted version in refcounted_context_keyed_service_factory.cc!
69 const auto& it = mapping_.find(context);
70 if (it != mapping_.end())
71 return it->second;
73 // Object not found.
74 if (!create)
75 return nullptr; // And we're forbidden from creating one.
77 // Create new object.
78 // Check to see if we have a per-context testing factory that we should use
79 // instead of default behavior.
80 scoped_ptr<KeyedService> service;
81 const auto& jt = testing_factories_.find(context);
82 if (jt != testing_factories_.end()) {
83 if (jt->second) {
84 if (!IsOffTheRecord(context))
85 RegisterUserPrefsOnContextForTest(context);
86 service = jt->second(context);
88 } else {
89 service = BuildServiceInstanceFor(context);
92 Associate(context, service.Pass());
93 return mapping_[context];
96 void KeyedServiceFactory::Associate(base::SupportsUserData* context,
97 scoped_ptr<KeyedService> service) {
98 DCHECK(!ContainsKey(mapping_, context));
99 mapping_.insert(std::make_pair(context, service.release()));
102 void KeyedServiceFactory::Disassociate(base::SupportsUserData* context) {
103 const auto& it = mapping_.find(context);
104 if (it != mapping_.end()) {
105 delete it->second;
106 mapping_.erase(it);
110 void KeyedServiceFactory::ContextShutdown(base::SupportsUserData* context) {
111 const auto& it = mapping_.find(context);
112 if (it != mapping_.end() && it->second)
113 it->second->Shutdown();
116 void KeyedServiceFactory::ContextDestroyed(base::SupportsUserData* context) {
117 Disassociate(context);
119 // For unit tests, we also remove the factory function both so we don't
120 // maintain a big map of dead pointers, but also since we may have a second
121 // object that lives at the same address (see other comments about unit tests
122 // in this file).
123 testing_factories_.erase(context);
125 KeyedServiceBaseFactory::ContextDestroyed(context);
128 void KeyedServiceFactory::SetEmptyTestingFactory(
129 base::SupportsUserData* context) {
130 SetTestingFactory(context, nullptr);
133 bool KeyedServiceFactory::HasTestingFactory(base::SupportsUserData* context) {
134 return testing_factories_.find(context) != testing_factories_.end();
137 void KeyedServiceFactory::CreateServiceNow(base::SupportsUserData* context) {
138 GetServiceForContext(context, true);