C++程序  |  109行  |  4.54 KB

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