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