| // Copyright 2014 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef EXTENSIONS_BROWSER_BROWSER_CONTEXT_KEYED_API_FACTORY_H_ | 
 | #define EXTENSIONS_BROWSER_BROWSER_CONTEXT_KEYED_API_FACTORY_H_ | 
 |  | 
 | #include "components/keyed_service/content/browser_context_dependency_manager.h" | 
 | #include "components/keyed_service/content/browser_context_keyed_service_factory.h" | 
 | #include "components/keyed_service/core/keyed_service.h" | 
 | #include "extensions/browser/extension_system_provider.h" | 
 | #include "extensions/browser/extensions_browser_client.h" | 
 |  | 
 | namespace extensions { | 
 |  | 
 | template <typename T> | 
 | class BrowserContextKeyedAPIFactory; | 
 |  | 
 | // Instantiations of BrowserContextKeyedAPIFactory should use this base class | 
 | // and also define a static const char* service_name() function (used in the | 
 | // BrowserContextKeyedServiceFactory constructor). These fields should | 
 | // be accessible to the BrowserContextKeyedAPIFactory for the service. | 
 | class BrowserContextKeyedAPI : public KeyedService { | 
 |  protected: | 
 |   // Defaults for flags that control BrowserContextKeyedAPIFactory behavior. | 
 |   // These can be overridden by subclasses to change that behavior. | 
 |   // See BrowserContextKeyedServiceFactory for usage. | 
 |  | 
 |   // These flags affect what instance is returned when Get() is called | 
 |   // on an incognito profile. By default, it returns NULL. If | 
 |   // kServiceRedirectedInIncognito is true, it returns the instance for the | 
 |   // corresponding regular profile. If kServiceHasOwnInstanceInIncognito | 
 |   // is true, it returns a separate instance. | 
 |   static const bool kServiceRedirectedInIncognito = false; | 
 |   static const bool kServiceHasOwnInstanceInIncognito = false; | 
 |  | 
 |   // This value forces the Guest profile to set its `ProfileSelection` with the | 
 |   // same value set for the Regular Profile. | 
 |   // If the value is false, then `ProfileSelection::kNone` will be used, and the | 
 |   // service will not be created for Guest profiles. | 
 |   static const bool kServiceIsCreatedInGuestMode = true; | 
 |  | 
 |   // If set to false, don't start the service at BrowserContext creation time. | 
 |   // (The default differs from the BrowserContextKeyedServiceFactory default, | 
 |   // because historically, BrowserContextKeyedAPIs often do tasks at startup.) | 
 |   static const bool kServiceIsCreatedWithBrowserContext = true; | 
 |  | 
 |   // If set to true, GetForProfile returns NULL for TestingBrowserContexts. | 
 |   static const bool kServiceIsNULLWhileTesting = false; | 
 |  | 
 |   // Users of this factory template must define a GetFactoryInstance() | 
 |   // and manage their own instances (using LazyInstance), because those cannot | 
 |   // be included in more than one translation unit (and thus cannot be | 
 |   // initialized in a header file). | 
 |   // | 
 |   // In the header file, declare GetFactoryInstance(), e.g.: | 
 |   //   class HistoryAPI { | 
 |   //   ... | 
 |   //    public: | 
 |   //     static BrowserContextKeyedAPIFactory<HistoryAPI>* GetFactoryInstance(); | 
 |   //   }; | 
 |   // | 
 |   // In the cc file, provide the implementation, e.g.: | 
 |   //   static base::LazyInstance<BrowserContextKeyedAPIFactory<HistoryAPI>>:: | 
 |   //      DestructorAtExit g_factory = LAZY_INSTANCE_INITIALIZER; | 
 |   // | 
 |   //   // static | 
 |   //   BrowserContextKeyedAPIFactory<HistoryAPI>* | 
 |   //   HistoryAPI::GetFactoryInstance() { | 
 |   //     return g_factory.Pointer(); | 
 |   //   } | 
 | }; | 
 |  | 
 | // Declare dependencies on other factories. | 
 | // By default, ChromeExtensionSystemFactory is the only dependency; however, | 
 | // specializations can override this. Declare your specialization in | 
 | // your header file after the BrowserContextKeyedAPI class definition. | 
 | // Declare this struct in the header file. The implementation may optionally | 
 | // be placed in your .cc file. | 
 | // This method should be used instead of | 
 | // BrowserContextKeyedAPIFactory<T>::DeclareFactoryDependencies() because it | 
 | // permits partial specialization, as in the case of ApiResourceManager<T>. | 
 | // | 
 | //   template <> | 
 | //   struct BrowserContextFactoryDependencies<MyService> { | 
 | //     static void DeclareFactoryDependencies( | 
 | //         BrowserContextKeyedAPIFactory<ApiResourceManager<T>>* factory) { | 
 | //       factory->DependsOn( | 
 | //           ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | 
 | //       factory->DependsOn(SyncServiceFactory::GetInstance()); | 
 | //       ... | 
 | //     } | 
 | //   }; | 
 | template <typename T> | 
 | struct BrowserContextFactoryDependencies { | 
 |   static void DeclareFactoryDependencies( | 
 |       BrowserContextKeyedAPIFactory<T>* factory) { | 
 |     if (ExtensionsBrowserClient::Get()) { | 
 |       factory->DependsOn( | 
 |           ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | 
 |     } | 
 |   } | 
 | }; | 
 |  | 
 | // A template for factories for KeyedServices that manage extension APIs. T is | 
 | // a KeyedService that uses this factory template instead of its own separate | 
 | // factory definition to manage its per-profile instances. | 
 | template <typename T> | 
 | class BrowserContextKeyedAPIFactory : public BrowserContextKeyedServiceFactory { | 
 |  public: | 
 |   using PassKey = base::PassKey<BrowserContextKeyedAPIFactory<T>>; | 
 |   static T* Get(content::BrowserContext* context) { | 
 |     return static_cast<T*>( | 
 |         T::GetFactoryInstance()->GetServiceForBrowserContext(context, true)); | 
 |   } | 
 |  | 
 |   static T* GetIfExists(content::BrowserContext* context) { | 
 |     return static_cast<T*>( | 
 |         T::GetFactoryInstance()->GetServiceForBrowserContext(context, false)); | 
 |   } | 
 |  | 
 |   // Declares dependencies on other factories. | 
 |   // Deprecated. Use BrowserContextFactoryDependencies<> to declare | 
 |   // dependencies instead, as that form allows for partial specializations like | 
 |   // in the case of ApiResourceManager<T>. | 
 |   void DeclareFactoryDependencies() { | 
 |     BrowserContextFactoryDependencies<T>::DeclareFactoryDependencies(this); | 
 |   } | 
 |  | 
 |   BrowserContextKeyedAPIFactory() | 
 |       : BrowserContextKeyedServiceFactory( | 
 |             T::service_name(), | 
 |             BrowserContextDependencyManager::GetInstance()) { | 
 |     DeclareFactoryDependencies(); | 
 |   } | 
 |  | 
 |   BrowserContextKeyedAPIFactory(const BrowserContextKeyedAPIFactory&) = delete; | 
 |   BrowserContextKeyedAPIFactory& operator=( | 
 |       const BrowserContextKeyedAPIFactory&) = delete; | 
 |  | 
 |   ~BrowserContextKeyedAPIFactory() override {} | 
 |  | 
 |  private: | 
 |   friend struct BrowserContextFactoryDependencies<T>; | 
 |  | 
 |   std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( | 
 |       content::BrowserContext* context) const override { | 
 |     return std::make_unique<T>(context); | 
 |   } | 
 |  | 
 |   // BrowserContextKeyedServiceFactory implementation. | 
 |   // These can be effectively overridden with template specializations. | 
 |   content::BrowserContext* GetBrowserContextToUse( | 
 |       content::BrowserContext* context) const override { | 
 |     // The GetContext...() implementations below treat guest sessions like | 
 |     // normal ones, so explicitly exclude guest sessions here if necessary. | 
 |     auto* const client = ExtensionsBrowserClient::Get(); | 
 |     if constexpr (!T::kServiceIsCreatedInGuestMode) { | 
 |       if (client->IsGuestSession(context)) { | 
 |         return nullptr; | 
 |       } | 
 |     } | 
 |  | 
 |     if constexpr (T::kServiceRedirectedInIncognito) { | 
 |       return client->GetContextRedirectedToOriginal(context); | 
 |     } else if constexpr (T::kServiceHasOwnInstanceInIncognito) { | 
 |       return client->GetContextOwnInstance(context); | 
 |     } else { | 
 |       return client->GetContextForOriginalOnly(context); | 
 |     } | 
 |   } | 
 |  | 
 |   bool ServiceIsCreatedWithBrowserContext() const override { | 
 |     return T::kServiceIsCreatedWithBrowserContext; | 
 |   } | 
 |  | 
 |   bool ServiceIsNULLWhileTesting() const override { | 
 |     return T::kServiceIsNULLWhileTesting; | 
 |   } | 
 | }; | 
 |  | 
 | }  // namespace extensions | 
 |  | 
 | #endif  // EXTENSIONS_BROWSER_BROWSER_CONTEXT_KEYED_API_FACTORY_H_ |