blob: 5b34b738203b0d3dccd49c1ab4d3a00ea66b122d [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_ARC_ARC_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_BASE_H_
#define COMPONENTS_ARC_ARC_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_BASE_H_
#include <memory>
#include "base/logging.h"
#include "base/macros.h"
#include "components/arc/arc_service_manager.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace content {
class BrowserContext;
} // namespace content
namespace arc {
namespace internal {
// Implementation of BrowserContextKeyedServiceFactory for ARC related
// services. The ARC related BrowserContextKeyedService can make its factory
// class derived from this class.
//
// How to use:
// In .h:
// #include "components/keyed_service/core/keyed_service.h"
//
// namespace content {
// class BrowserContext;
// } // namespace content
//
// class ArcFooService : public KeyedService, ... {
// public:
// static ArcFooService* GetForBrowserContext(
// content::BrowserContext* context);
//
// ArcFooService(content::BrowserContext* context,
// ArcBridgeService* arc_bridge_service);
// };
//
// In .cc:
//
// namespace {
// class ArcFooServiceFactory
// : public internal::ArcBrowserContextKeyedServiceFactoryBase<
// ArcFooService,
// ArcFooServiceFactory> {
// public:
// static constexpr const char* kName = "ArcFooServiceFactory";
//
// static ArcFooServiceFactory* GetInstance() {
// return base::Singleton<ArcFooServiceFactory>::get();
// }
//
// private:
// friend struct base::DefaultSingletonTraits<ArcFooServiceFactory>;
// ArcFooServiceFactory() = default;
// ~ArcFooServiceFactory() override = default;
// };
// } // namespace
//
// ArcFooService* ArcFooService::GetForBrowserContext(
// content::BrowserContext* context) {
// return ArcFooServiceFactory::GetForBrowserContext(context);
// }
//
// If the service depends on other KeyedService, DependsOn() can be called in
// the factory's ctor similar to other BrowserContextKeyedServiceFactory
// subclasses.
//
// This header is intended to be included only from the .cc file directly.
//
// TODO(hidehiko): Make ArcFooService constructor (and maybe destructor)
// private with declaring appropriate friend.
template <typename Service, typename Factory>
class ArcBrowserContextKeyedServiceFactoryBase
: public BrowserContextKeyedServiceFactory {
public:
// Returns the instance of the service for the given |context|,
// or nullptr if |context| is not allowed to use ARC.
// If the instance is not yet created, this creates a new service instance.
static Service* GetForBrowserContext(content::BrowserContext* context) {
return static_cast<Service*>(
Factory::GetInstance()->GetServiceForBrowserContext(context,
true /* create */));
}
// Does the same as GetForBrowserContext() but for testing. This should be
// called from the |Service|'s unit test's fixture to instantiate the service.
// Note that this function does not check whether or not |context| is for the
// primary user. Also, ArcServiceManager has to be instantiated before calling
// this function.
static Service* GetForBrowserContextForTesting(
content::BrowserContext* context) {
Factory::GetInstance()->SetTestingFactoryAndUse(
context,
[](content::BrowserContext* context) -> std::unique_ptr<KeyedService> {
return std::make_unique<Service>(
context, ArcServiceManager::Get()->arc_bridge_service());
});
return GetForBrowserContext(context);
}
protected:
ArcBrowserContextKeyedServiceFactoryBase()
: BrowserContextKeyedServiceFactory(
Factory::kName,
BrowserContextDependencyManager::GetInstance()) {}
~ArcBrowserContextKeyedServiceFactoryBase() override = default;
// BrowserContextKeyedServiceFactory override:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override {
auto* arc_service_manager = arc::ArcServiceManager::Get();
// Practically, this is in testing case.
if (!arc_service_manager) {
VLOG(2) << "ArcServiceManager is not available.";
return nullptr;
}
if (arc_service_manager->browser_context() != context) {
VLOG(2) << "Non ARC allowed browser context.";
return nullptr;
}
return new Service(context, arc_service_manager->arc_bridge_service());
}
private:
DISALLOW_COPY_AND_ASSIGN(ArcBrowserContextKeyedServiceFactoryBase);
};
} // namespace internal
} // namespace arc
#endif // COMPONENTS_ARC_ARC_BROWSER_CONTEXT_KEYED_SERVICE_FACTORY_BASE_H_