refcounted_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/refcounted_browser_context_keyed_service_factory.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/stl_util.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/content/refcounted_browser_context_keyed_service.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/browser_context.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RefcountedBrowserContextKeyedServiceFactory::SetTestingFactory( 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context, 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TestingFactoryFunction testing_factory) { 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Destroying the context may cause us to lose data about whether |context| 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // has our preferences registered on it (since the context object itself 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // isn't dead). See if we need to readd it once we've gone through normal 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // destruction. 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool add_context = ArePreferencesSetOn(context); 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We have to go through the shutdown and destroy mechanisms because there 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // are unit tests that create a service on a context and then change the 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // testing service mid-test. 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextShutdown(context); 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextDestroyed(context); 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (add_context) 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MarkPreferencesSetOn(context); 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) testing_factories_[context] = testing_factory; 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_refptr<RefcountedBrowserContextKeyedService> 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)RefcountedBrowserContextKeyedServiceFactory::SetTestingFactoryAndUse( 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context, 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TestingFactoryFunction testing_factory) { 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(testing_factory); 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetTestingFactory(context, testing_factory); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return GetServiceForBrowserContext(context, true); 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)RefcountedBrowserContextKeyedServiceFactory:: 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RefcountedBrowserContextKeyedServiceFactory( 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* name, 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContextDependencyManager* manager) 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : BrowserContextKeyedBaseFactory(name, manager) {} 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)RefcountedBrowserContextKeyedServiceFactory:: 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ~RefcountedBrowserContextKeyedServiceFactory() { 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(mapping_.empty()); 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_refptr<RefcountedBrowserContextKeyedService> 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)RefcountedBrowserContextKeyedServiceFactory::GetServiceForBrowserContext( 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context, 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool create) { 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) context = GetBrowserContextToUse(context); 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!context) 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NOTE: If you modify any of the logic below, make sure to update the 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // non-refcounted version in context_keyed_service_factory.cc! 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RefCountedStorage::const_iterator it = mapping_.find(context); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it != mapping_.end()) 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return it->second; 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Object not found. 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!create) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return NULL; // And we're forbidden from creating one. 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create new object. 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check to see if we have a per-BrowserContext testing factory that we should 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // use instead of default behavior. 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<RefcountedBrowserContextKeyedService> service; 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserContextOverriddenTestingFunctions::const_iterator jt = 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) testing_factories_.find(context); 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (jt != testing_factories_.end()) { 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (jt->second) { 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!context->IsOffTheRecord()) 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RegisterUserPrefsOnBrowserContextForTest(context); 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) service = jt->second(context); 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) service = BuildServiceInstanceFor(context); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Associate(context, service); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return service; 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RefcountedBrowserContextKeyedServiceFactory::Associate( 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context, 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const scoped_refptr<RefcountedBrowserContextKeyedService>& service) { 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!ContainsKey(mapping_, context)); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mapping_.insert(std::make_pair(context, service)); 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RefcountedBrowserContextKeyedServiceFactory::BrowserContextShutdown( 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RefCountedStorage::iterator it = mapping_.find(context); 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it != mapping_.end() && it->second.get()) 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it->second->ShutdownOnUIThread(); 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RefcountedBrowserContextKeyedServiceFactory::BrowserContextDestroyed( 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We "merely" drop our reference to the service. Hopefully this will cause 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the service to be destroyed. If not, oh well. 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mapping_.erase(context); 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // For unit tests, we also remove the factory function both so we don't 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // maintain a big map of dead pointers, but also since we may have a second 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // object that lives at the same address (see other comments about unit tests 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // in this file). 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) testing_factories_.erase(context); 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserContextKeyedBaseFactory::BrowserContextDestroyed(context); 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RefcountedBrowserContextKeyedServiceFactory::SetEmptyTestingFactory( 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetTestingFactory(context, NULL); 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool RefcountedBrowserContextKeyedServiceFactory::HasTestingFactory( 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserContext* context) { 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return testing_factories_.find(context) != testing_factories_.end(); 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RefcountedBrowserContextKeyedServiceFactory::CreateServiceNow( 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* context) { 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetServiceForBrowserContext(context, true); 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 135