Home | History | Annotate | Download | only in browser
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef EXTENSIONS_BROWSER_BROWSER_CONTEXT_KEYED_API_FACTORY_H_
      6 #define EXTENSIONS_BROWSER_BROWSER_CONTEXT_KEYED_API_FACTORY_H_
      7 
      8 #include "components/keyed_service/content/browser_context_dependency_manager.h"
      9 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
     10 #include "components/keyed_service/core/keyed_service.h"
     11 #include "extensions/browser/extension_system_provider.h"
     12 #include "extensions/browser/extensions_browser_client.h"
     13 
     14 namespace extensions {
     15 
     16 template <typename T>
     17 class BrowserContextKeyedAPIFactory;
     18 
     19 // Instantiations of BrowserContextKeyedAPIFactory should use this base class
     20 // and also define a static const char* service_name() function (used in the
     21 // BrowserContextKeyedBaseFactory constructor). These fields should
     22 // be accessible to the BrowserContextKeyedAPIFactory for the service.
     23 class BrowserContextKeyedAPI : public KeyedService {
     24  protected:
     25   // Defaults for flags that control BrowserContextKeyedAPIFactory behavior.
     26   // These can be overridden by subclasses to change that behavior.
     27   // See BrowserContextKeyedBaseFactory for usage.
     28 
     29   // These flags affect what instance is returned when Get() is called
     30   // on an incognito profile. By default, it returns NULL. If
     31   // kServiceRedirectedInIncognito is true, it returns the instance for the
     32   // corresponding regular profile. If kServiceHasOwnInstanceInIncognito
     33   // is true, it returns a separate instance.
     34   static const bool kServiceRedirectedInIncognito = false;
     35   static const bool kServiceHasOwnInstanceInIncognito = false;
     36 
     37   // If set to false, don't start the service at BrowserContext creation time.
     38   // (The default differs from the BrowserContextKeyedBaseFactory default,
     39   // because historically, BrowserContextKeyedAPIs often do tasks at startup.)
     40   static const bool kServiceIsCreatedWithBrowserContext = true;
     41 
     42   // If set to true, GetForProfile returns NULL for TestingBrowserContexts.
     43   static const bool kServiceIsNULLWhileTesting = false;
     44 
     45   // Users of this factory template must define a GetFactoryInstance()
     46   // and manage their own instances (typically using LazyInstance or
     47   // Singleton), because those cannot be included in more than one
     48   // translation unit (and thus cannot be initialized in a header file).
     49   //
     50   // In the header file, declare GetFactoryInstance(), e.g.:
     51   //   class HistoryAPI {
     52   //   ...
     53   //    public:
     54   //     static BrowserContextKeyedAPIFactory<HistoryAPI>* GetFactoryInstance();
     55   //   };
     56   //
     57   // In the cc file, provide the implementation, e.g.:
     58   //   static base::LazyInstance<BrowserContextKeyedAPIFactory<HistoryAPI> >
     59   //   g_factory = LAZY_INSTANCE_INITIALIZER;
     60   //
     61   //   // static
     62   //   BrowserContextKeyedAPIFactory<HistoryAPI>*
     63   //   HistoryAPI::GetFactoryInstance() {
     64   //     return g_factory.Pointer();
     65   //   }
     66 };
     67 
     68 // A template for factories for KeyedServices that manage extension APIs. T is
     69 // a KeyedService that uses this factory template instead of its own separate
     70 // factory definition to manage its per-profile instances.
     71 template <typename T>
     72 class BrowserContextKeyedAPIFactory : public BrowserContextKeyedServiceFactory {
     73  public:
     74   static T* Get(content::BrowserContext* context) {
     75     return static_cast<T*>(
     76         T::GetFactoryInstance()->GetServiceForBrowserContext(context, true));
     77   }
     78 
     79   // Declare dependencies on other factories.
     80   // By default, ExtensionSystemFactory is the only dependency; however,
     81   // specializations can override this. Declare your specialization in
     82   // your header file after the BrowserContextKeyedAPI class definition.
     83   // Then in the cc file (or inline in the header), define it, e.g.:
     84   //   template <>
     85   //   void BrowserContextKeyedAPIFactory<
     86   //       PushMessagingAPI>::DeclareFactoryDependencies() {
     87   //     DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
     88   //     DependsOn(ProfileSyncServiceFactory::GetInstance());
     89   //   }
     90   void DeclareFactoryDependencies() {
     91     DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
     92   }
     93 
     94   BrowserContextKeyedAPIFactory()
     95       : BrowserContextKeyedServiceFactory(
     96             T::service_name(),
     97             BrowserContextDependencyManager::GetInstance()) {
     98     DeclareFactoryDependencies();
     99   }
    100 
    101   virtual ~BrowserContextKeyedAPIFactory() {}
    102 
    103  private:
    104   // BrowserContextKeyedServiceFactory implementation.
    105   virtual KeyedService* BuildServiceInstanceFor(
    106       content::BrowserContext* context) const OVERRIDE {
    107     return new T(context);
    108   }
    109 
    110   // BrowserContextKeyedBaseFactory implementation.
    111   // These can be effectively overridden with template specializations.
    112   virtual content::BrowserContext* GetBrowserContextToUse(
    113       content::BrowserContext* context) const OVERRIDE {
    114     if (T::kServiceRedirectedInIncognito)
    115       return ExtensionsBrowserClient::Get()->GetOriginalContext(context);
    116 
    117     if (T::kServiceHasOwnInstanceInIncognito)
    118       return context;
    119 
    120     return BrowserContextKeyedServiceFactory::GetBrowserContextToUse(context);
    121   }
    122 
    123   virtual bool ServiceIsCreatedWithBrowserContext() const OVERRIDE {
    124     return T::kServiceIsCreatedWithBrowserContext;
    125   }
    126 
    127   virtual bool ServiceIsNULLWhileTesting() const OVERRIDE {
    128     return T::kServiceIsNULLWhileTesting;
    129   }
    130 
    131   DISALLOW_COPY_AND_ASSIGN(BrowserContextKeyedAPIFactory);
    132 };
    133 
    134 }  // namespace extensions
    135 
    136 #endif  // EXTENSIONS_BROWSER_BROWSER_CONTEXT_KEYED_API_FACTORY_H_
    137