OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/keyed_service/content/refcounted_browser_context_keyed_serv
ice_factory.h" | 5 #include "components/keyed_service/content/refcounted_browser_context_keyed_serv
ice_factory.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/prefs/pref_service.h" |
8 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "components/keyed_service/content/browser_context_dependency_manager.h" |
9 #include "components/keyed_service/core/keyed_service.h" | 11 #include "components/keyed_service/core/keyed_service.h" |
10 #include "components/keyed_service/core/refcounted_keyed_service.h" | 12 #include "components/keyed_service/core/refcounted_keyed_service.h" |
| 13 #include "components/pref_registry/pref_registry_syncable.h" |
| 14 #include "components/user_prefs/user_prefs.h" |
11 #include "content/public/browser/browser_context.h" | 15 #include "content/public/browser/browser_context.h" |
12 | 16 |
13 void RefcountedBrowserContextKeyedServiceFactory::SetTestingFactory( | 17 void RefcountedBrowserContextKeyedServiceFactory::SetTestingFactory( |
14 content::BrowserContext* context, | 18 content::BrowserContext* context, |
15 TestingFactoryFunction testing_factory) { | 19 TestingFactoryFunction testing_factory) { |
16 // Destroying the context may cause us to lose data about whether |context| | 20 RefcountedKeyedServiceFactory::SetTestingFactory( |
17 // has our preferences registered on it (since the context object itself | 21 context, |
18 // isn't dead). See if we need to readd it once we've gone through normal | 22 reinterpret_cast<RefcountedKeyedServiceFactory::TestingFactoryFunction>( |
19 // destruction. | 23 testing_factory)); |
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 } | 24 } |
33 | 25 |
34 scoped_refptr<RefcountedKeyedService> | 26 scoped_refptr<RefcountedKeyedService> |
35 RefcountedBrowserContextKeyedServiceFactory::SetTestingFactoryAndUse( | 27 RefcountedBrowserContextKeyedServiceFactory::SetTestingFactoryAndUse( |
36 content::BrowserContext* context, | 28 content::BrowserContext* context, |
37 TestingFactoryFunction testing_factory) { | 29 TestingFactoryFunction testing_factory) { |
38 DCHECK(testing_factory); | 30 return RefcountedKeyedServiceFactory::SetTestingFactoryAndUse( |
39 SetTestingFactory(context, testing_factory); | 31 context, |
40 return GetServiceForBrowserContext(context, true); | 32 reinterpret_cast<RefcountedKeyedServiceFactory::TestingFactoryFunction>( |
| 33 testing_factory)); |
41 } | 34 } |
42 | 35 |
43 RefcountedBrowserContextKeyedServiceFactory:: | 36 RefcountedBrowserContextKeyedServiceFactory:: |
44 RefcountedBrowserContextKeyedServiceFactory( | 37 RefcountedBrowserContextKeyedServiceFactory( |
45 const char* name, | 38 const char* name, |
46 BrowserContextDependencyManager* manager) | 39 BrowserContextDependencyManager* manager) |
47 : BrowserContextKeyedBaseFactory(name, manager) {} | 40 : RefcountedKeyedServiceFactory(name, manager) { |
| 41 } |
48 | 42 |
49 RefcountedBrowserContextKeyedServiceFactory:: | 43 RefcountedBrowserContextKeyedServiceFactory:: |
50 ~RefcountedBrowserContextKeyedServiceFactory() { | 44 ~RefcountedBrowserContextKeyedServiceFactory() { |
51 DCHECK(mapping_.empty()); | |
52 } | 45 } |
53 | 46 |
54 scoped_refptr<RefcountedKeyedService> | 47 scoped_refptr<RefcountedKeyedService> |
55 RefcountedBrowserContextKeyedServiceFactory::GetServiceForBrowserContext( | 48 RefcountedBrowserContextKeyedServiceFactory::GetServiceForBrowserContext( |
56 content::BrowserContext* context, | 49 content::BrowserContext* context, |
57 bool create) { | 50 bool create) { |
58 context = GetBrowserContextToUse(context); | 51 return RefcountedKeyedServiceFactory::GetServiceForContext(context, create); |
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<RefcountedKeyedService> 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 } | 52 } |
91 | 53 |
92 void RefcountedBrowserContextKeyedServiceFactory::Associate( | 54 content::BrowserContext* |
93 content::BrowserContext* context, | 55 RefcountedBrowserContextKeyedServiceFactory::GetBrowserContextToUse( |
94 const scoped_refptr<RefcountedKeyedService>& service) { | 56 content::BrowserContext* context) const { |
95 DCHECK(!ContainsKey(mapping_, context)); | 57 DCHECK(CalledOnValidThread()); |
96 mapping_.insert(std::make_pair(context, service)); | 58 |
| 59 #ifndef NDEBUG |
| 60 AssertContextWasntDestroyed(context); |
| 61 #endif |
| 62 |
| 63 // Safe default for Incognito mode: no service. |
| 64 if (context->IsOffTheRecord()) |
| 65 return nullptr; |
| 66 |
| 67 return context; |
| 68 } |
| 69 |
| 70 void RefcountedBrowserContextKeyedServiceFactory:: |
| 71 RegisterUserPrefsOnBrowserContextForTest(content::BrowserContext* context) { |
| 72 KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(context); |
| 73 } |
| 74 |
| 75 bool RefcountedBrowserContextKeyedServiceFactory:: |
| 76 ServiceIsCreatedWithBrowserContext() const { |
| 77 return KeyedServiceBaseFactory::ServiceIsCreatedWithContext(); |
| 78 } |
| 79 |
| 80 bool RefcountedBrowserContextKeyedServiceFactory::ServiceIsNULLWhileTesting() |
| 81 const { |
| 82 return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting(); |
97 } | 83 } |
98 | 84 |
99 void RefcountedBrowserContextKeyedServiceFactory::BrowserContextShutdown( | 85 void RefcountedBrowserContextKeyedServiceFactory::BrowserContextShutdown( |
100 content::BrowserContext* context) { | 86 content::BrowserContext* context) { |
101 RefCountedStorage::iterator it = mapping_.find(context); | 87 RefcountedKeyedServiceFactory::ContextShutdown(context); |
102 if (it != mapping_.end() && it->second.get()) | |
103 it->second->ShutdownOnUIThread(); | |
104 } | 88 } |
105 | 89 |
106 void RefcountedBrowserContextKeyedServiceFactory::BrowserContextDestroyed( | 90 void RefcountedBrowserContextKeyedServiceFactory::BrowserContextDestroyed( |
107 content::BrowserContext* context) { | 91 content::BrowserContext* context) { |
108 // We "merely" drop our reference to the service. Hopefully this will cause | 92 RefcountedKeyedServiceFactory::ContextDestroyed(context); |
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 } | 93 } |
120 | 94 |
121 void RefcountedBrowserContextKeyedServiceFactory::SetEmptyTestingFactory( | 95 scoped_refptr<RefcountedKeyedService> |
122 content::BrowserContext* context) { | 96 RefcountedBrowserContextKeyedServiceFactory::BuildServiceInstanceFor( |
123 SetTestingFactory(context, NULL); | 97 base::SupportsUserData* context) const { |
| 98 return BuildServiceInstanceFor( |
| 99 static_cast<content::BrowserContext*>(context)); |
124 } | 100 } |
125 | 101 |
126 bool RefcountedBrowserContextKeyedServiceFactory::HasTestingFactory( | 102 bool RefcountedBrowserContextKeyedServiceFactory::IsOffTheRecord( |
127 content::BrowserContext* context) { | 103 base::SupportsUserData* context) const { |
128 return testing_factories_.find(context) != testing_factories_.end(); | 104 return static_cast<content::BrowserContext*>(context)->IsOffTheRecord(); |
129 } | 105 } |
130 | 106 |
131 void RefcountedBrowserContextKeyedServiceFactory::CreateServiceNow( | 107 user_prefs::PrefRegistrySyncable* |
132 content::BrowserContext* context) { | 108 RefcountedBrowserContextKeyedServiceFactory::GetAssociatedPrefRegistry( |
133 GetServiceForBrowserContext(context, true); | 109 base::SupportsUserData* context) const { |
| 110 PrefService* prefs = user_prefs::UserPrefs::Get( |
| 111 static_cast<content::BrowserContext*>(context)); |
| 112 user_prefs::PrefRegistrySyncable* registry = |
| 113 static_cast<user_prefs::PrefRegistrySyncable*>( |
| 114 prefs->DeprecatedGetPrefRegistry()); |
| 115 return registry; |
134 } | 116 } |
| 117 |
| 118 base::SupportsUserData* |
| 119 RefcountedBrowserContextKeyedServiceFactory::GetContextToUse( |
| 120 base::SupportsUserData* context) const { |
| 121 return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context)); |
| 122 } |
| 123 |
| 124 bool RefcountedBrowserContextKeyedServiceFactory::ServiceIsCreatedWithContext() |
| 125 const { |
| 126 return ServiceIsCreatedWithBrowserContext(); |
| 127 } |
| 128 |
| 129 void RefcountedBrowserContextKeyedServiceFactory::ContextShutdown( |
| 130 base::SupportsUserData* context) { |
| 131 BrowserContextShutdown(static_cast<content::BrowserContext*>(context)); |
| 132 } |
| 133 |
| 134 void RefcountedBrowserContextKeyedServiceFactory::ContextDestroyed( |
| 135 base::SupportsUserData* context) { |
| 136 BrowserContextDestroyed(static_cast<content::BrowserContext*>(context)); |
| 137 } |
| 138 |
| 139 void RefcountedBrowserContextKeyedServiceFactory::RegisterPrefs( |
| 140 user_prefs::PrefRegistrySyncable* registry) { |
| 141 RegisterProfilePrefs(registry); |
| 142 } |
OLD | NEW |