| Index: components/keyed_service/content/browser_context_keyed_service_factory.cc
|
| diff --git a/components/keyed_service/content/browser_context_keyed_service_factory.cc b/components/keyed_service/content/browser_context_keyed_service_factory.cc
|
| index a33ffedbe48a4bc330dfd5d28c16aa7af364288e..2eb002dfa6bf6c709e16036d68e3c67dd8cd1cfe 100644
|
| --- a/components/keyed_service/content/browser_context_keyed_service_factory.cc
|
| +++ b/components/keyed_service/content/browser_context_keyed_service_factory.cc
|
| @@ -4,144 +4,156 @@
|
|
|
| #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
|
|
|
| -#include <map>
|
| -
|
| #include "base/logging.h"
|
| +#include "base/prefs/pref_service.h"
|
| #include "base/stl_util.h"
|
| #include "components/keyed_service/content/browser_context_dependency_manager.h"
|
| #include "components/keyed_service/core/keyed_service.h"
|
| +#include "components/pref_registry/pref_registry_syncable.h"
|
| +#include "components/user_prefs/user_prefs.h"
|
| #include "content/public/browser/browser_context.h"
|
|
|
| void BrowserContextKeyedServiceFactory::SetTestingFactory(
|
| content::BrowserContext* context,
|
| TestingFactoryFunction testing_factory) {
|
| - // Destroying the context may cause us to lose data about whether |context|
|
| - // has our preferences registered on it (since the context object itself
|
| - // isn't dead). See if we need to readd it once we've gone through normal
|
| - // destruction.
|
| - bool add_context = ArePreferencesSetOn(context);
|
| -
|
| -#ifndef NDEBUG
|
| - // Ensure that |context| is not marked as stale (e.g., due to it aliasing an
|
| - // instance that was destroyed in an earlier test) in order to avoid accesses
|
| - // to |context| in |BrowserContextShutdown| from causing
|
| - // |AssertBrowserContextWasntDestroyed| to raise an error.
|
| - MarkContextLiveForTesting(context);
|
| -#endif
|
| -
|
| - // We have to go through the shutdown and destroy mechanisms because there
|
| - // are unit tests that create a service on a context and then change the
|
| - // testing service mid-test.
|
| - BrowserContextShutdown(context);
|
| - BrowserContextDestroyed(context);
|
| -
|
| - if (add_context)
|
| - MarkPreferencesSetOn(context);
|
| -
|
| - testing_factories_[context] = testing_factory;
|
| + KeyedServiceFactory::SetTestingFactory(
|
| + context,
|
| + reinterpret_cast<KeyedServiceFactory::TestingFactoryFunction>(
|
| + testing_factory));
|
| }
|
|
|
| KeyedService* BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
|
| content::BrowserContext* context,
|
| TestingFactoryFunction testing_factory) {
|
| - DCHECK(testing_factory);
|
| - SetTestingFactory(context, testing_factory);
|
| - return GetServiceForBrowserContext(context, true);
|
| + return KeyedServiceFactory::SetTestingFactoryAndUse(
|
| + context,
|
| + reinterpret_cast<KeyedServiceFactory::TestingFactoryFunction>(
|
| + testing_factory));
|
| }
|
|
|
| BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory(
|
| const char* name,
|
| BrowserContextDependencyManager* manager)
|
| - : BrowserContextKeyedBaseFactory(name, manager) {}
|
| + : KeyedServiceFactory(name, manager) {
|
| +}
|
|
|
| BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
|
| - DCHECK(mapping_.empty());
|
| }
|
|
|
| KeyedService* BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
|
| content::BrowserContext* context,
|
| bool create) {
|
| - context = GetBrowserContextToUse(context);
|
| - if (!context)
|
| - return NULL;
|
| -
|
| - // NOTE: If you modify any of the logic below, make sure to update the
|
| - // refcounted version in refcounted_context_keyed_service_factory.cc!
|
| - BrowserContextKeyedServices::const_iterator it = mapping_.find(context);
|
| - if (it != mapping_.end())
|
| - return it->second;
|
| -
|
| - // Object not found.
|
| - if (!create)
|
| - return NULL; // And we're forbidden from creating one.
|
| -
|
| - // Create new object.
|
| - // Check to see if we have a per-BrowserContext testing factory that we should
|
| - // use instead of default behavior.
|
| - KeyedService* service = NULL;
|
| - BrowserContextOverriddenTestingFunctions::const_iterator jt =
|
| - testing_factories_.find(context);
|
| - if (jt != testing_factories_.end()) {
|
| - if (jt->second) {
|
| - if (!context->IsOffTheRecord())
|
| - RegisterUserPrefsOnBrowserContextForTest(context);
|
| - service = jt->second(context);
|
| - }
|
| - } else {
|
| - service = BuildServiceInstanceFor(context);
|
| - }
|
| -
|
| - Associate(context, service);
|
| - return service;
|
| -}
|
| -
|
| -void BrowserContextKeyedServiceFactory::Associate(
|
| - content::BrowserContext* context,
|
| - KeyedService* service) {
|
| - DCHECK(!ContainsKey(mapping_, context));
|
| - mapping_.insert(std::make_pair(context, service));
|
| + return KeyedServiceFactory::GetServiceForContext(context, create);
|
| +}
|
| +
|
| +content::BrowserContext*
|
| +BrowserContextKeyedServiceFactory::GetBrowserContextToUse(
|
| + content::BrowserContext* context) const {
|
| + DCHECK(CalledOnValidThread());
|
| +
|
| +#ifndef NDEBUG
|
| + AssertContextWasntDestroyed(context);
|
| +#endif
|
| +
|
| + // Safe default for Incognito mode: no service.
|
| + if (context->IsOffTheRecord())
|
| + return nullptr;
|
| +
|
| + return context;
|
| }
|
|
|
| -void BrowserContextKeyedServiceFactory::Disassociate(
|
| +void
|
| +BrowserContextKeyedServiceFactory::RegisterUserPrefsOnBrowserContextForTest(
|
| content::BrowserContext* context) {
|
| - BrowserContextKeyedServices::iterator it = mapping_.find(context);
|
| - if (it != mapping_.end()) {
|
| - delete it->second;
|
| - mapping_.erase(it);
|
| - }
|
| + KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(context);
|
| +}
|
| +
|
| +bool BrowserContextKeyedServiceFactory::ServiceIsCreatedWithBrowserContext()
|
| + const {
|
| + return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
|
| +}
|
| +
|
| +bool BrowserContextKeyedServiceFactory::ServiceIsNULLWhileTesting() const {
|
| + return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting();
|
| }
|
|
|
| void BrowserContextKeyedServiceFactory::BrowserContextShutdown(
|
| content::BrowserContext* context) {
|
| - BrowserContextKeyedServices::iterator it = mapping_.find(context);
|
| - if (it != mapping_.end() && it->second)
|
| - it->second->Shutdown();
|
| + KeyedServiceFactory::ContextShutdown(context);
|
| }
|
|
|
| void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
|
| content::BrowserContext* context) {
|
| - Disassociate(context);
|
| + KeyedServiceFactory::ContextDestroyed(context);
|
| +}
|
|
|
| - // For unit tests, we also remove the factory function both so we don't
|
| - // maintain a big map of dead pointers, but also since we may have a second
|
| - // object that lives at the same address (see other comments about unit tests
|
| - // in this file).
|
| - testing_factories_.erase(context);
|
| +KeyedService* BrowserContextKeyedServiceFactory::BuildServiceInstanceFor(
|
| + base::SupportsUserData* context) const {
|
| + return BuildServiceInstanceFor(
|
| + static_cast<content::BrowserContext*>(context));
|
| +}
|
|
|
| - BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context);
|
| +bool BrowserContextKeyedServiceFactory::IsOffTheRecord(
|
| + base::SupportsUserData* context) const {
|
| + return static_cast<content::BrowserContext*>(context)->IsOffTheRecord();
|
| }
|
|
|
| -void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory(
|
| - content::BrowserContext* context) {
|
| - SetTestingFactory(context, NULL);
|
| +user_prefs::PrefRegistrySyncable*
|
| +BrowserContextKeyedServiceFactory::GetAssociatedPrefRegistry(
|
| + base::SupportsUserData* context) const {
|
| + // Safe timing for pref registration is hard. Previously, we made
|
| + // BrowserContext responsible for all pref registration on every service
|
| + // that used BrowserContext. Now we don't and there are timing issues.
|
| + //
|
| + // With normal contexts, prefs can simply be registered at
|
| + // BrowserContextDependencyManager::RegisterProfilePrefsForServices time.
|
| + // With incognito contexts, we just never register since incognito contexts
|
| + // share the same pref services with their parent contexts.
|
| + //
|
| + // TestingBrowserContexts throw a wrench into the mix, in that some tests will
|
| + // swap out the PrefService after we've registered user prefs on the original
|
| + // PrefService. Test code that does this is responsible for either manually
|
| + // invoking RegisterProfilePrefs() on the appropriate
|
| + // BrowserContextKeyedServiceFactory associated with the prefs they need,
|
| + // or they can use SetTestingFactory() and create a service (since service
|
| + // creation with a factory method causes registration to happen at
|
| + // TestingProfile creation time).
|
| + //
|
| + // Now that services are responsible for declaring their preferences, we have
|
| + // to enforce a uniquenes check here because some tests create one context and
|
| + // multiple services of the same type attached to that context (serially, not
|
| + // parallel) and we don't want to register multiple times on the same context.
|
| + // This is the purpose of RegisterProfilePrefsIfNecessary() which could be
|
| + // replaced directly by RegisterProfilePrefs() if this method is ever phased
|
| + // out.
|
| + PrefService* prefs = user_prefs::UserPrefs::Get(
|
| + static_cast<content::BrowserContext*>(context));
|
| + user_prefs::PrefRegistrySyncable* registry =
|
| + static_cast<user_prefs::PrefRegistrySyncable*>(
|
| + prefs->DeprecatedGetPrefRegistry());
|
| + return registry;
|
| }
|
|
|
| -bool BrowserContextKeyedServiceFactory::HasTestingFactory(
|
| - content::BrowserContext* context) {
|
| - return testing_factories_.find(context) != testing_factories_.end();
|
| +base::SupportsUserData* BrowserContextKeyedServiceFactory::GetContextToUse(
|
| + base::SupportsUserData* context) const {
|
| + return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
|
| }
|
|
|
| -void BrowserContextKeyedServiceFactory::CreateServiceNow(
|
| - content::BrowserContext* context) {
|
| - GetServiceForBrowserContext(context, true);
|
| +bool BrowserContextKeyedServiceFactory::ServiceIsCreatedWithContext() const {
|
| + return ServiceIsCreatedWithBrowserContext();
|
| +}
|
| +
|
| +void BrowserContextKeyedServiceFactory::ContextShutdown(
|
| + base::SupportsUserData* context) {
|
| + BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
|
| +}
|
| +
|
| +void BrowserContextKeyedServiceFactory::ContextDestroyed(
|
| + base::SupportsUserData* context) {
|
| + BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
|
| +}
|
| +
|
| +void BrowserContextKeyedServiceFactory::RegisterPrefs(
|
| + user_prefs::PrefRegistrySyncable* registry) {
|
| + RegisterProfilePrefs(registry);
|
| }
|
|
|