1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
// 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_
|