browser_context_keyed_service_factory.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/content/browser_context_keyed_service_factory.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <map> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/stl_util.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/content/browser_context_dependency_manager.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/browser_context.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextKeyedServiceFactory::SetTestingFactory( 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::BrowserContext* context, 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TestingFactoryFunction testing_factory) { 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Destroying the context may cause us to lose data about whether |context| 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // has our preferences registered on it (since the context object itself 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // isn't dead). See if we need to readd it once we've gone through normal 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // destruction. 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool add_context = ArePreferencesSetOn(context); 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef NDEBUG 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensure that |context| is not marked as stale (e.g., due to it aliasing an 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // instance that was destroyed in an earlier test) in order to avoid accesses 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to |context| in |BrowserContextShutdown| from causing 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |AssertBrowserContextWasntDestroyed| to raise an error. 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dependency_manager_->MarkBrowserContextLiveForTesting(context); 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We have to go through the shutdown and destroy mechanisms because there 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // are unit tests that create a service on a context and then change the 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // testing service mid-test. 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextShutdown(context); 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextDestroyed(context); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (add_context) 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MarkPreferencesSetOn(context); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) testing_factories_[context] = testing_factory; 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)KeyedService* BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse( 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context, 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TestingFactoryFunction testing_factory) { 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(testing_factory); 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetTestingFactory(context, testing_factory); 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return GetServiceForBrowserContext(context, true); 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory( 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* name, 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContextDependencyManager* manager) 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : BrowserContextKeyedBaseFactory(name, manager) {} 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() { 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(mapping_.empty()); 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)KeyedService* BrowserContextKeyedServiceFactory::GetServiceForBrowserContext( 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context, 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool create) { 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) context = GetBrowserContextToUse(context); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!context) 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NOTE: If you modify any of the logic below, make sure to update the 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // refcounted version in refcounted_context_keyed_service_factory.cc! 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedServices::const_iterator it = mapping_.find(context); 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it != mapping_.end()) 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return it->second; 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Object not found. 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!create) 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; // And we're forbidden from creating one. 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create new object. 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check to see if we have a per-BrowserContext testing factory that we should 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // use instead of default behavior. 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) KeyedService* service = NULL; 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserContextOverriddenTestingFunctions::const_iterator jt = 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) testing_factories_.find(context); 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (jt != testing_factories_.end()) { 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (jt->second) { 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!context->IsOffTheRecord()) 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RegisterUserPrefsOnBrowserContextForTest(context); 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) service = jt->second(context); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) service = BuildServiceInstanceFor(context); 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Associate(context, service); 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return service; 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextKeyedServiceFactory::Associate( 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context, 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) KeyedService* service) { 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!ContainsKey(mapping_, context)); 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mapping_.insert(std::make_pair(context, service)); 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BrowserContextKeyedServiceFactory::Disassociate( 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* context) { 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContextKeyedServices::iterator it = mapping_.find(context); 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it != mapping_.end()) { 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delete it->second; 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mapping_.erase(it); 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextKeyedServiceFactory::BrowserContextShutdown( 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedServices::iterator it = mapping_.find(context); 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it != mapping_.end() && it->second) 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it->second->Shutdown(); 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextKeyedServiceFactory::BrowserContextDestroyed( 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Disassociate(context); 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // For unit tests, we also remove the factory function both so we don't 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // maintain a big map of dead pointers, but also since we may have a second 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // object that lives at the same address (see other comments about unit tests 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // in this file). 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) testing_factories_.erase(context); 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context); 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextKeyedServiceFactory::SetEmptyTestingFactory( 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetTestingFactory(context, NULL); 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool BrowserContextKeyedServiceFactory::HasTestingFactory( 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserContext* context) { 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return testing_factories_.find(context) != testing_factories_.end(); 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void BrowserContextKeyedServiceFactory::CreateServiceNow( 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetServiceForBrowserContext(context, true); 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 148