Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / components / browser_context_keyed_service / browser_context_keyed_service_factory.cc
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, 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
20   // destruction.
21   bool add_context = ArePreferencesSetOn(context);
22
23 #ifndef NDEBUG
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);
29 #endif
30
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);
36
37   if (add_context)
38     MarkPreferencesSetOn(context);
39
40   testing_factories_[context] = testing_factory;
41 }
42
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);
50 }
51
52 BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory(
53     const char* name, BrowserContextDependencyManager* manager)
54     : BrowserContextKeyedBaseFactory(name, manager) {
55 }
56
57 BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
58   DCHECK(mapping_.empty());
59 }
60
61 BrowserContextKeyedService*
62 BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
63     content::BrowserContext* context,
64     bool create) {
65   context = GetBrowserContextToUse(context);
66   if (!context)
67     return NULL;
68
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())
73     return it->second;
74
75   // Object not found.
76   if (!create)
77     return NULL;  // And we're forbidden from creating one.
78
79   // Create new object.
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()) {
86     if (jt->second) {
87       if (!context->IsOffTheRecord())
88         RegisterUserPrefsOnBrowserContextForTest(context);
89       service = jt->second(context);
90     }
91   } else {
92     service = BuildServiceInstanceFor(context);
93   }
94
95   Associate(context, service);
96   return service;
97 }
98
99 void BrowserContextKeyedServiceFactory::Associate(
100     content::BrowserContext* context,
101     BrowserContextKeyedService* service) {
102   DCHECK(!ContainsKey(mapping_, context));
103   mapping_.insert(std::make_pair(context, service));
104 }
105
106 void BrowserContextKeyedServiceFactory::Disassociate(
107     content::BrowserContext* context) {
108   BrowserContextKeyedServices::iterator it = mapping_.find(context);
109   if (it != mapping_.end()) {
110     delete it->second;
111     mapping_.erase(it);
112   }
113 }
114
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();
120 }
121
122 void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
123     content::BrowserContext* context) {
124   Disassociate(context);
125
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
129   // in this file).
130   testing_factories_.erase(context);
131
132   BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context);
133 }
134
135 void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
136     content::BrowserContext* context) {
137   SetTestingFactory(context, NULL);
138 }
139
140 void BrowserContextKeyedServiceFactory::CreateServiceNow(
141     content::BrowserContext* context) {
142   GetServiceForBrowserContext(context, true);
143 }