1 // Copyright (c) 2012 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 CHROME_BROWSER_EXTENSIONS_API_PROFILE_KEYED_API_FACTORY_H_ 6 #define CHROME_BROWSER_EXTENSIONS_API_PROFILE_KEYED_API_FACTORY_H_ 7 8 #include "chrome/browser/extensions/extension_system_factory.h" 9 #include "chrome/browser/profiles/incognito_helpers.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h" 12 #include "components/browser_context_keyed_service/browser_context_keyed_service.h" 13 #include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h" 14 15 namespace extensions { 16 17 template <typename T> 18 class ProfileKeyedAPIFactory; 19 20 // Instantiations of ProfileKeyedAPIFactory should use this base class 21 // and also define a static const char* service_name() function (used in the 22 // BrowserContextKeyedBaseFactory constructor). These fields should 23 // be accessible to the ProfileKeyedAPIFactory for the service. 24 class ProfileKeyedAPI : public BrowserContextKeyedService { 25 protected: 26 // Defaults for flags that control ProfileKeyedAPIFactory behavior. 27 // See BrowserContextKeyedBaseFactory for usage. 28 static const bool kServiceRedirectedInIncognito = false; 29 static const bool kServiceIsNULLWhileTesting = false; 30 static const bool kServiceHasOwnInstanceInIncognito = false; 31 static const bool kServiceIsCreatedWithBrowserContext = true; 32 33 // Users of this factory template must define a GetFactoryInstance() 34 // and manage their own instances (typically using LazyInstance or 35 // Singleton), because those cannot be included in more than one 36 // translation unit (and thus cannot be initialized in a header file). 37 // 38 // In the header file, declare GetFactoryInstance(), e.g.: 39 // class ProcessesAPI { 40 // ... 41 // public: 42 // static ProfileKeyedAPIFactory<ProcessesAPI>* GetFactoryInstance(); 43 // }; 44 // 45 // In the cc file, provide the implementation, e.g.: 46 // static base::LazyInstance<ProfileKeyedAPIFactory<ProcessesAPI> > 47 // g_factory = LAZY_INSTANCE_INITIALIZER; 48 // 49 // // static 50 // ProfileKeyedAPIFactory<ProcessesAPI>* 51 // ProcessesAPI::GetFactoryInstance() { 52 // return &g_factory.Get(); 53 // } 54 }; 55 56 // A template for factories for BrowserContextKeyedServices that manage 57 // extension APIs. T is a BrowserContextKeyedService that uses this factory 58 // template instead of its own separate factory definition to manage its 59 // per-profile instances. 60 template <typename T> 61 class ProfileKeyedAPIFactory : public BrowserContextKeyedServiceFactory { 62 public: GetForProfile(Profile * profile)63 static T* GetForProfile(Profile* profile) { 64 return static_cast<T*>( 65 T::GetFactoryInstance()->GetServiceForBrowserContext(profile, true)); 66 } 67 68 // Declare dependencies on other factories. 69 // By default, ExtensionSystemFactory is the only dependency; however, 70 // specializations can override this. Declare your specialization in 71 // your header file after the ProfileKeyedAPI class definition. 72 // Then in the cc file (or inline in the header), define it, e.g.: 73 // template <> 74 // ProfileKeyedAPIFactory<PushMessagingAPI>::DeclareFactoryDependencies() { 75 // DependsOn(ExtensionSystemFactory::GetInstance()); 76 // DependsOn(ProfileSyncServiceFactory::GetInstance()); 77 // } DeclareFactoryDependencies()78 void DeclareFactoryDependencies() { 79 DependsOn(ExtensionSystemFactory::GetInstance()); 80 } 81 ProfileKeyedAPIFactory()82 ProfileKeyedAPIFactory() 83 : BrowserContextKeyedServiceFactory( 84 T::service_name(), 85 BrowserContextDependencyManager::GetInstance()) { 86 DeclareFactoryDependencies(); 87 } 88 ~ProfileKeyedAPIFactory()89 virtual ~ProfileKeyedAPIFactory() { 90 } 91 92 private: 93 // BrowserContextKeyedServiceFactory implementation. BuildServiceInstanceFor(content::BrowserContext * profile)94 virtual BrowserContextKeyedService* BuildServiceInstanceFor( 95 content::BrowserContext* profile) const OVERRIDE { 96 return new T(static_cast<Profile*>(profile)); 97 } 98 99 // BrowserContextKeyedBaseFactory implementation. 100 // These can be effectively overridden with template specializations. GetBrowserContextToUse(content::BrowserContext * context)101 virtual content::BrowserContext* GetBrowserContextToUse( 102 content::BrowserContext* context) const OVERRIDE { 103 if (T::kServiceRedirectedInIncognito) 104 return chrome::GetBrowserContextRedirectedInIncognito(context); 105 106 if (T::kServiceHasOwnInstanceInIncognito) 107 return chrome::GetBrowserContextOwnInstanceInIncognito(context); 108 109 return BrowserContextKeyedServiceFactory::GetBrowserContextToUse(context); 110 } 111 ServiceIsCreatedWithBrowserContext()112 virtual bool ServiceIsCreatedWithBrowserContext() const OVERRIDE { 113 return T::kServiceIsCreatedWithBrowserContext; 114 } 115 ServiceIsNULLWhileTesting()116 virtual bool ServiceIsNULLWhileTesting() const OVERRIDE { 117 return T::kServiceIsNULLWhileTesting; 118 } 119 120 DISALLOW_COPY_AND_ASSIGN(ProfileKeyedAPIFactory); 121 }; 122 123 } // namespace extensions 124 125 #endif // CHROME_BROWSER_EXTENSIONS_API_PROFILE_KEYED_API_FACTORY_H_ 126