| 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 |