// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_FACTORY_H_ #define CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_FACTORY_H_ #include <map> class Profile; class ProfileDependencyManager; class ProfileKeyedService; // Base class for Factories that take a Profile object and return some service // on a one-to-one mapping. Each factory that derives from this class *must* // be a Singleton (only unit tests don't do that). See ThemeServiceFactory as // an example of how to derive from this class. // // We do this because services depend on each other and we need to control // shutdown/destruction order. In each derived classes' constructors, the // implementors must explicitly state which services are depended on. class ProfileKeyedServiceFactory { public: typedef ProfileKeyedService* (*FactoryFunction)(Profile* profile); #if defined(UNIT_TEST) // Associate an already-created |service| with |profile| for this factory. // The service may be a mock, or may be NULL to inhibit automatic creation of // the service by the default function. A mock factory set with // |set_test_factory| will be called instead if the service is NULL. void ForceAssociationBetween(Profile* profile, ProfileKeyedService* service) { Associate(profile, service); } // Sets the factory function to use to create mock instances of this service. // The factory function will only be called for profiles for which // |ForceAssociationBetween| has been previously called with a NULL service // pointer, and therefore does not affect normal non-test profiles. void set_test_factory(FactoryFunction factory) { factory_ = factory; } #endif protected: // ProfileKeyedServiceFactories must communicate with a // ProfileDependencyManager. For all non-test code, write your subclass // constructors like this: // // MyServiceFactory::MyServiceFactory() // : ProfileKeyedServiceFactory( // ProfileDependencyManager::GetInstance()) // {} explicit ProfileKeyedServiceFactory(ProfileDependencyManager* manager); virtual ~ProfileKeyedServiceFactory(); // Common implementation that maps |profile| to some service object. Deals // with incognito profiles per subclass instructions with // ServiceActiveInIncognito(). ProfileKeyedService* GetServiceForProfile(Profile* profile); // The main public interface for declaring dependencies between services // created by factories. void DependsOn(ProfileKeyedServiceFactory* rhs); // Maps |profile| to |provider| with debug checks to prevent duplication. void Associate(Profile* profile, ProfileKeyedService* service); // Returns a new instance of the service, casted to void* for our common // storage. virtual ProfileKeyedService* BuildServiceInstanceFor( Profile* profile) const = 0; // By default, if we are asked for a service with an Incognito profile, we // pass back NULL. To redirect to the Incognito's original profile or to // create another instance, even for Incognito windows, override one of the // following methods: virtual bool ServiceRedirectedInIncognito(); virtual bool ServiceHasOwnInstanceInIncognito(); // A helper object actually listens for notifications about Profile // destruction, calculates the order in which things are destroyed and then // does a two pass shutdown. // // First, ProfileShutdown() is called on every ServiceFactory and will // usually call ProfileKeyedService::Shutdown(), which gives each // ProfileKeyedService a chance to remove dependencies on other services that // it may be holding. // // Secondly, ProfileDestroyed() is called on every ServiceFactory and the // default implementation removes it from |mapping_| and deletes the pointer. virtual void ProfileShutdown(Profile* profile); virtual void ProfileDestroyed(Profile* profile); private: friend class ProfileDependencyManager; friend class ProfileDependencyManagerUnittests; // The mapping between a Profile and its service. std::map<Profile*, ProfileKeyedService*> mapping_; // Which ProfileDependencyManager we should communicate with. In real code, // this will always be ProfileDependencyManager::GetInstance(), but unit // tests will want to use their own copy. ProfileDependencyManager* dependency_manager_; // A mock factory function to use to create the service, used by tests. FactoryFunction factory_; }; #endif // CHROME_BROWSER_PROFILES_PROFILE_KEYED_SERVICE_FACTORY_H_