- add sources.
[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, FactoryFunction 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   // We have to go through the shutdown and destroy mechanisms because there
24   // are unit tests that create a service on a context and then change the
25   // testing service mid-test.
26   BrowserContextShutdown(context);
27   BrowserContextDestroyed(context);
28
29   if (add_context)
30     MarkPreferencesSetOn(context);
31
32   factories_[context] = factory;
33 }
34
35 BrowserContextKeyedService*
36 BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
37     content::BrowserContext* context,
38     FactoryFunction factory) {
39   DCHECK(factory);
40   SetTestingFactory(context, factory);
41   return GetServiceForBrowserContext(context, true);
42 }
43
44 BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory(
45     const char* name, BrowserContextDependencyManager* manager)
46     : BrowserContextKeyedBaseFactory(name, manager) {
47 }
48
49 BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
50   DCHECK(mapping_.empty());
51 }
52
53 BrowserContextKeyedService*
54 BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
55     content::BrowserContext* context,
56     bool create) {
57   context = GetBrowserContextToUse(context);
58   if (!context)
59     return NULL;
60
61   // NOTE: If you modify any of the logic below, make sure to update the
62   // refcounted version in refcounted_context_keyed_service_factory.cc!
63   BrowserContextKeyedServices::const_iterator it = mapping_.find(context);
64   if (it != mapping_.end())
65     return it->second;
66
67   // Object not found.
68   if (!create)
69     return NULL;  // And we're forbidden from creating one.
70
71   // Create new object.
72   // Check to see if we have a per-BrowserContext testing factory that we should
73   // use instead of default behavior.
74   BrowserContextKeyedService* service = NULL;
75   BrowserContextOverriddenFunctions::const_iterator jt =
76       factories_.find(context);
77   if (jt != factories_.end()) {
78     if (jt->second) {
79       if (!context->IsOffTheRecord())
80         RegisterUserPrefsOnBrowserContext(context);
81       service = jt->second(context);
82     }
83   } else {
84     service = BuildServiceInstanceFor(context);
85   }
86
87   Associate(context, service);
88   return service;
89 }
90
91 void BrowserContextKeyedServiceFactory::Associate(
92     content::BrowserContext* context,
93     BrowserContextKeyedService* service) {
94   DCHECK(!ContainsKey(mapping_, context));
95   mapping_.insert(std::make_pair(context, service));
96 }
97
98 void BrowserContextKeyedServiceFactory::BrowserContextShutdown(
99     content::BrowserContext* context) {
100   BrowserContextKeyedServices::iterator it = mapping_.find(context);
101   if (it != mapping_.end() && it->second)
102     it->second->Shutdown();
103 }
104
105 void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
106     content::BrowserContext* context) {
107   BrowserContextKeyedServices::iterator it = mapping_.find(context);
108   if (it != mapping_.end()) {
109     delete it->second;
110     mapping_.erase(it);
111   }
112
113   // For unit tests, we also remove the factory function both so we don't
114   // maintain a big map of dead pointers, but also since we may have a second
115   // object that lives at the same address (see other comments about unit tests
116   // in this file).
117   factories_.erase(context);
118
119   BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context);
120 }
121
122 void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
123     content::BrowserContext* context) {
124   SetTestingFactory(context, NULL);
125 }
126
127 void BrowserContextKeyedServiceFactory::CreateServiceNow(
128     content::BrowserContext* context) {
129   GetServiceForBrowserContext(context, true);
130 }