Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / components / keyed_service / content / refcounted_browser_context_keyed_service_factory.cc
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.
4
5 #include "components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h"
6
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"
12
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
19   // destruction.
20   bool add_context = ArePreferencesSetOn(context);
21
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);
27
28   if (add_context)
29     MarkPreferencesSetOn(context);
30
31   testing_factories_[context] = testing_factory;
32 }
33
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);
41 }
42
43 RefcountedBrowserContextKeyedServiceFactory::
44     RefcountedBrowserContextKeyedServiceFactory(
45         const char* name,
46         BrowserContextDependencyManager* manager)
47     : BrowserContextKeyedBaseFactory(name, manager) {}
48
49 RefcountedBrowserContextKeyedServiceFactory::
50     ~RefcountedBrowserContextKeyedServiceFactory() {
51   DCHECK(mapping_.empty());
52 }
53
54 scoped_refptr<RefcountedBrowserContextKeyedService>
55 RefcountedBrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
56     content::BrowserContext* context,
57     bool create) {
58   context = GetBrowserContextToUse(context);
59   if (!context)
60     return NULL;
61
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())
66     return it->second;
67
68   // Object not found.
69   if (!create)
70     return NULL;  // And we're forbidden from creating one.
71
72   // Create new object.
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()) {
79     if (jt->second) {
80       if (!context->IsOffTheRecord())
81         RegisterUserPrefsOnBrowserContextForTest(context);
82       service = jt->second(context);
83     }
84   } else {
85     service = BuildServiceInstanceFor(context);
86   }
87
88   Associate(context, service);
89   return service;
90 }
91
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));
97 }
98
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();
104 }
105
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);
111
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
115   // in this file).
116   testing_factories_.erase(context);
117
118   BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context);
119 }
120
121 void RefcountedBrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
122     content::BrowserContext* context) {
123   SetTestingFactory(context, NULL);
124 }
125
126 bool RefcountedBrowserContextKeyedServiceFactory::HasTestingFactory(
127     content::BrowserContext* context) {
128   return testing_factories_.find(context) != testing_factories_.end();
129 }
130
131 void RefcountedBrowserContextKeyedServiceFactory::CreateServiceNow(
132     content::BrowserContext* context) {
133   GetServiceForBrowserContext(context, true);
134 }