Commit bc4ea7f7 authored by Troy Hildebrandt's avatar Troy Hildebrandt Committed by Commit Bot

Add a ProtoDatabaseProvider as a keyed service.

Adds a ProtoDatabaseProvider(Factory) to provide ProtoDatabases with
the user directory, with ProtoDatabaseProvider as a
BrowserContextKeyedService.

Since ProtoDatabase is just an interface, and the underlying
implementation of it can vary from client to client, a
ProtoDatabaseWrapper that contains a pointer to a ProtoDatabase is
created, also built off ProtoDatabase.

Modifies the Feature Engagement Tracker to use the new provider for
its two databases.

Bug: 870813
Change-Id: I26376a14e8280605b7e3431862e5fe3ad6b9c8db
Reviewed-on: https://chromium-review.googlesource.com/c/1318053Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avataredchin <edchin@chromium.org>
Reviewed-by: default avatarRohit Rao <rohitrao@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Commit-Queue: Troy Hildebrandt <thildebr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611878}
parent c4740eae
...@@ -1794,6 +1794,7 @@ jumbo_split_static_library("browser") { ...@@ -1794,6 +1794,7 @@ jumbo_split_static_library("browser") {
"//components/keyed_service/content", "//components/keyed_service/content",
"//components/language/content/browser", "//components/language/content/browser",
"//components/language/core/browser", "//components/language/core/browser",
"//components/leveldb_proto/content:factory",
"//components/live_tab_count_metrics", "//components/live_tab_count_metrics",
"//components/metrics:call_stack_profile_collector", "//components/metrics:call_stack_profile_collector",
"//components/metrics:component_metrics", "//components/metrics:component_metrics",
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_constants.h"
#include "components/feature_engagement/public/tracker.h" #include "components/feature_engagement/public/tracker.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/leveldb_proto/content/proto_database_provider_factory.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
namespace feature_engagement { namespace feature_engagement {
...@@ -33,7 +34,9 @@ feature_engagement::Tracker* TrackerFactory::GetForBrowserContext( ...@@ -33,7 +34,9 @@ feature_engagement::Tracker* TrackerFactory::GetForBrowserContext(
TrackerFactory::TrackerFactory() TrackerFactory::TrackerFactory()
: BrowserContextKeyedServiceFactory( : BrowserContextKeyedServiceFactory(
"feature_engagement::Tracker", "feature_engagement::Tracker",
BrowserContextDependencyManager::GetInstance()) {} BrowserContextDependencyManager::GetInstance()) {
DependsOn(leveldb_proto::ProtoDatabaseProviderFactory::GetInstance());
}
TrackerFactory::~TrackerFactory() = default; TrackerFactory::~TrackerFactory() = default;
...@@ -48,8 +51,11 @@ KeyedService* TrackerFactory::BuildServiceInstanceFor( ...@@ -48,8 +51,11 @@ KeyedService* TrackerFactory::BuildServiceInstanceFor(
base::FilePath storage_dir = profile->GetPath().Append( base::FilePath storage_dir = profile->GetPath().Append(
chrome::kFeatureEngagementTrackerStorageDirname); chrome::kFeatureEngagementTrackerStorageDirname);
return feature_engagement::Tracker::Create(storage_dir, leveldb_proto::ProtoDatabaseProvider* db_provider =
background_task_runner); leveldb_proto::ProtoDatabaseProviderFactory::GetInstance()
->GetForBrowserContext(context);
return feature_engagement::Tracker::Create(
storage_dir, background_task_runner, db_provider);
} }
content::BrowserContext* TrackerFactory::GetBrowserContextToUse( content::BrowserContext* TrackerFactory::GetBrowserContextToUse(
......
...@@ -146,8 +146,7 @@ void PersistentAvailabilityStore::LoadAndUpdateStore( ...@@ -146,8 +146,7 @@ void PersistentAvailabilityStore::LoadAndUpdateStore(
PersistentAvailabilityStore::OnLoadedCallback on_loaded_callback, PersistentAvailabilityStore::OnLoadedCallback on_loaded_callback,
uint32_t current_day) { uint32_t current_day) {
auto* db_ptr = db.get(); auto* db_ptr = db.get();
db_ptr->Init(kDatabaseUMAName, storage_dir, db_ptr->Init(kDatabaseUMAName,
leveldb_proto::CreateSimpleOptions(),
base::BindOnce(&OnDBInitComplete, std::move(db), base::BindOnce(&OnDBInitComplete, std::move(db),
std::move(feature_filter), std::move(feature_filter),
std::move(on_loaded_callback), current_day)); std::move(on_loaded_callback), current_day));
......
...@@ -94,17 +94,6 @@ class PersistentAvailabilityStoreTest : public testing::Test { ...@@ -94,17 +94,6 @@ class PersistentAvailabilityStoreTest : public testing::Test {
} // namespace } // namespace
TEST_F(PersistentAvailabilityStoreTest, StorageDirectory) {
PersistentAvailabilityStore::LoadAndUpdateStore(
storage_dir_, CreateDB(), FeatureVector(), std::move(load_callback_),
14u);
db_->InitCallback(true);
EXPECT_EQ(storage_dir_, db_->GetDirectory());
// Finish the pipeline to ensure the test does not leak anything.
db_->LoadCallback(false);
}
TEST_F(PersistentAvailabilityStoreTest, InitFail) { TEST_F(PersistentAvailabilityStoreTest, InitFail) {
PersistentAvailabilityStore::LoadAndUpdateStore( PersistentAvailabilityStore::LoadAndUpdateStore(
storage_dir_, CreateDB(), FeatureVector(), std::move(load_callback_), storage_dir_, CreateDB(), FeatureVector(), std::move(load_callback_),
......
...@@ -25,19 +25,15 @@ void NoopUpdateCallback(bool success) { ...@@ -25,19 +25,15 @@ void NoopUpdateCallback(bool success) {
} // namespace } // namespace
PersistentEventStore::PersistentEventStore( PersistentEventStore::PersistentEventStore(
const base::FilePath& storage_dir,
std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db) std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db)
: storage_dir_(storage_dir), : db_(std::move(db)), ready_(false), weak_ptr_factory_(this) {}
db_(std::move(db)),
ready_(false),
weak_ptr_factory_(this) {}
PersistentEventStore::~PersistentEventStore() = default; PersistentEventStore::~PersistentEventStore() = default;
void PersistentEventStore::Load(const OnLoadedCallback& callback) { void PersistentEventStore::Load(const OnLoadedCallback& callback) {
DCHECK(!ready_); DCHECK(!ready_);
db_->Init(kDBUMAName, storage_dir_, leveldb_proto::CreateSimpleOptions(), db_->Init(kDBUMAName,
base::BindOnce(&PersistentEventStore::OnInitComplete, base::BindOnce(&PersistentEventStore::OnInitComplete,
weak_ptr_factory_.GetWeakPtr(), callback)); weak_ptr_factory_.GetWeakPtr(), callback));
} }
...@@ -48,6 +44,7 @@ bool PersistentEventStore::IsReady() const { ...@@ -48,6 +44,7 @@ bool PersistentEventStore::IsReady() const {
void PersistentEventStore::WriteEvent(const Event& event) { void PersistentEventStore::WriteEvent(const Event& event) {
DCHECK(IsReady()); DCHECK(IsReady());
std::unique_ptr<KeyEventList> entries = std::make_unique<KeyEventList>(); std::unique_ptr<KeyEventList> entries = std::make_unique<KeyEventList>();
entries->push_back(KeyEventPair(event.name(), event)); entries->push_back(KeyEventPair(event.name(), event));
......
...@@ -23,10 +23,8 @@ namespace feature_engagement { ...@@ -23,10 +23,8 @@ namespace feature_engagement {
// to always save every write during shutdown. // to always save every write during shutdown.
class PersistentEventStore : public EventStore { class PersistentEventStore : public EventStore {
public: public:
// Builds a PersistentEventStore backed by the ProtoDatabase |db|. The // Builds a PersistentEventStore backed by the ProtoDatabase |db|.
// database will be loaded and/or created at |storage_dir|. PersistentEventStore(std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db);
PersistentEventStore(const base::FilePath& storage_dir,
std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> db);
~PersistentEventStore() override; ~PersistentEventStore() override;
// EventStore implementation. // EventStore implementation.
......
...@@ -33,9 +33,7 @@ void VerifyEventsInListAndMap(const std::map<std::string, Event>& map, ...@@ -33,9 +33,7 @@ void VerifyEventsInListAndMap(const std::map<std::string, Event>& map,
class PersistentEventStoreTest : public ::testing::Test { class PersistentEventStoreTest : public ::testing::Test {
public: public:
PersistentEventStoreTest() PersistentEventStoreTest() : db_(nullptr) {
: db_(nullptr),
storage_dir_(FILE_PATH_LITERAL("/persistent/store/lalala")) {
load_callback_ = base::Bind(&PersistentEventStoreTest::LoadCallback, load_callback_ = base::Bind(&PersistentEventStoreTest::LoadCallback,
base::Unretained(this)); base::Unretained(this));
} }
...@@ -53,7 +51,7 @@ class PersistentEventStoreTest : public ::testing::Test { ...@@ -53,7 +51,7 @@ class PersistentEventStoreTest : public ::testing::Test {
auto db = std::make_unique<leveldb_proto::test::FakeDB<Event>>(&db_events_); auto db = std::make_unique<leveldb_proto::test::FakeDB<Event>>(&db_events_);
db_ = db.get(); db_ = db.get();
store_.reset(new PersistentEventStore(storage_dir_, std::move(db))); store_.reset(new PersistentEventStore(std::move(db)));
} }
void LoadCallback(bool success, std::unique_ptr<std::vector<Event>> events) { void LoadCallback(bool success, std::unique_ptr<std::vector<Event>> events) {
...@@ -69,19 +67,10 @@ class PersistentEventStoreTest : public ::testing::Test { ...@@ -69,19 +67,10 @@ class PersistentEventStoreTest : public ::testing::Test {
std::map<std::string, Event> db_events_; std::map<std::string, Event> db_events_;
leveldb_proto::test::FakeDB<Event>* db_; leveldb_proto::test::FakeDB<Event>* db_;
std::unique_ptr<EventStore> store_; std::unique_ptr<EventStore> store_;
// Constant test data.
base::FilePath storage_dir_;
}; };
} // namespace } // namespace
TEST_F(PersistentEventStoreTest, StorageDirectory) {
SetUpDB();
store_->Load(load_callback_);
EXPECT_EQ(storage_dir_, db_->GetDirectory());
}
TEST_F(PersistentEventStoreTest, SuccessfulInitAndLoadEmptyStore) { TEST_F(PersistentEventStoreTest, SuccessfulInitAndLoadEmptyStore) {
SetUpDB(); SetUpDB();
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/feature_constants.h"
#include "components/feature_engagement/public/feature_list.h" #include "components/feature_engagement/public/feature_list.h"
#include "components/leveldb_proto/proto_database_impl.h" #include "components/leveldb_proto/proto_database_impl.h"
#include "components/leveldb_proto/proto_database_provider.h"
namespace feature_engagement { namespace feature_engagement {
...@@ -91,18 +92,18 @@ std::unique_ptr<Tracker> CreateDemoModeTracker() { ...@@ -91,18 +92,18 @@ std::unique_ptr<Tracker> CreateDemoModeTracker() {
// static // static
Tracker* Tracker::Create( Tracker* Tracker::Create(
const base::FilePath& storage_dir, const base::FilePath& storage_dir,
const scoped_refptr<base::SequencedTaskRunner>& background_task_runner) { const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
leveldb_proto::ProtoDatabaseProvider* db_provider) {
DVLOG(2) << "Creating Tracker"; DVLOG(2) << "Creating Tracker";
if (base::FeatureList::IsEnabled(kIPHDemoMode)) if (base::FeatureList::IsEnabled(kIPHDemoMode))
return CreateDemoModeTracker().release(); return CreateDemoModeTracker().release();
std::unique_ptr<leveldb_proto::ProtoDatabase<Event>> event_db =
std::make_unique<leveldb_proto::ProtoDatabaseImpl<Event>>(
background_task_runner);
base::FilePath event_storage_dir = storage_dir.Append(kEventDBStorageDir); base::FilePath event_storage_dir = storage_dir.Append(kEventDBStorageDir);
auto event_store = std::make_unique<PersistentEventStore>( auto event_db =
event_storage_dir, std::move(event_db)); db_provider->GetDB<Event>(event_storage_dir, background_task_runner);
auto event_store =
std::make_unique<PersistentEventStore>(std::move(event_db));
auto configuration = std::make_unique<ChromeVariationsConfiguration>(); auto configuration = std::make_unique<ChromeVariationsConfiguration>();
configuration->ParseFeatureConfigs(GetAllFeatures()); configuration->ParseFeatureConfigs(GetAllFeatures());
...@@ -122,9 +123,8 @@ Tracker* Tracker::Create( ...@@ -122,9 +123,8 @@ Tracker* Tracker::Create(
base::FilePath availability_storage_dir = base::FilePath availability_storage_dir =
storage_dir.Append(kAvailabilityDBStorageDir); storage_dir.Append(kAvailabilityDBStorageDir);
auto availability_db = auto availability_db = db_provider->GetDB<Availability>(
std::make_unique<leveldb_proto::ProtoDatabaseImpl<Availability>>( availability_storage_dir, background_task_runner);
background_task_runner);
auto availability_store_loader = base::BindOnce( auto availability_store_loader = base::BindOnce(
&PersistentAvailabilityStore::LoadAndUpdateStore, &PersistentAvailabilityStore::LoadAndUpdateStore,
availability_storage_dir, std::move(availability_db), GetAllFeatures()); availability_storage_dir, std::move(availability_db), GetAllFeatures());
......
...@@ -22,6 +22,10 @@ ...@@ -22,6 +22,10 @@
#include "base/android/jni_android.h" #include "base/android/jni_android.h"
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
namespace leveldb_proto {
class ProtoDatabaseProvider;
}
namespace feature_engagement { namespace feature_engagement {
// A handle for the display lock. While this is unreleased, no in-product help // A handle for the display lock. While this is unreleased, no in-product help
...@@ -71,7 +75,8 @@ class Tracker : public KeyedService { ...@@ -71,7 +75,8 @@ class Tracker : public KeyedService {
// The |bakground_task_runner| will be used for all disk reads and writes. // The |bakground_task_runner| will be used for all disk reads and writes.
static Tracker* Create( static Tracker* Create(
const base::FilePath& storage_dir, const base::FilePath& storage_dir,
const scoped_refptr<base::SequencedTaskRunner>& background_task_runner); const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
leveldb_proto::ProtoDatabaseProvider* db_provider);
// Must be called whenever an event happens. // Must be called whenever an event happens.
virtual void NotifyEvent(const std::string& event) = 0; virtual void NotifyEvent(const std::string& event) = 0;
......
...@@ -9,6 +9,9 @@ static_library("leveldb_proto") { ...@@ -9,6 +9,9 @@ static_library("leveldb_proto") {
"proto_database.cc", "proto_database.cc",
"proto_database.h", "proto_database.h",
"proto_database_impl.h", "proto_database_impl.h",
"proto_database_provider.cc",
"proto_database_provider.h",
"proto_database_wrapper.h",
"proto_leveldb_wrapper.cc", "proto_leveldb_wrapper.cc",
"proto_leveldb_wrapper.h", "proto_leveldb_wrapper.h",
"proto_leveldb_wrapper_metrics.cc", "proto_leveldb_wrapper_metrics.cc",
...@@ -18,6 +21,7 @@ static_library("leveldb_proto") { ...@@ -18,6 +21,7 @@ static_library("leveldb_proto") {
public_deps = [ public_deps = [
"//base", "//base",
"//components/keyed_service/core",
"//third_party/leveldatabase", "//third_party/leveldatabase",
] ]
} }
......
include_rules = [ include_rules = [
"+components/keyed_service/core",
"+third_party/leveldatabase", "+third_party/leveldatabase",
] ]
# Copyright 2014 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.
source_set("factory") {
sources = [
"proto_database_provider_factory.cc",
"proto_database_provider_factory.h",
]
public_deps = [
"//base",
"//components/keyed_service/content",
]
deps = [
"//content/public/browser",
]
}
include_rules = [
"+components/keyed_service/content",
"+content/public/browser",
]
\ No newline at end of file
// Copyright 2018 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.
#include "components/leveldb_proto/content/proto_database_provider_factory.h"
#include "base/files/file_path.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/leveldb_proto/proto_database_provider.h"
#include "content/public/browser/browser_context.h"
namespace leveldb_proto {
// static
ProtoDatabaseProviderFactory* ProtoDatabaseProviderFactory::GetInstance() {
return base::Singleton<ProtoDatabaseProviderFactory>::get();
}
// static
leveldb_proto::ProtoDatabaseProvider*
ProtoDatabaseProviderFactory::GetForBrowserContext(
content::BrowserContext* context) {
return static_cast<leveldb_proto::ProtoDatabaseProvider*>(
GetInstance()->GetServiceForBrowserContext(context, true));
}
ProtoDatabaseProviderFactory::ProtoDatabaseProviderFactory()
: BrowserContextKeyedServiceFactory(
"leveldb_proto::ProtoDatabaseProvider",
BrowserContextDependencyManager::GetInstance()) {}
ProtoDatabaseProviderFactory::~ProtoDatabaseProviderFactory() = default;
KeyedService* ProtoDatabaseProviderFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
base::FilePath profile_dir = context->GetPath();
return leveldb_proto::ProtoDatabaseProvider::Create(profile_dir);
}
} // namespace leveldb_proto
// Copyright 2018 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_LEVELDB_PROTO_CONTENT_PROTO_DATABASE_PROVIDER_FACTORY_H_
#define COMPONENTS_LEVELDB_PROTO_CONTENT_PROTO_DATABASE_PROVIDER_FACTORY_H_
#include "base/macros.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace base {
template <typename T>
struct DefaultSingletonTraits;
} // namespace base
namespace leveldb_proto {
class ProtoDatabaseProvider;
// A factory for ProtoDatabaseProvider, a class that provides proto databases
// stored in the appropriate directory for the current profile.
class ProtoDatabaseProviderFactory : public BrowserContextKeyedServiceFactory {
public:
// Returns singleton instance of ProtoDatabaseProviderFactory.
static ProtoDatabaseProviderFactory* GetInstance();
// Returns ProtoDatabaseProvider associated with |context|, so we can
// instantiate ProtoDatabases that use the appropriate profile directory.
static ProtoDatabaseProvider* GetForBrowserContext(
content::BrowserContext* context);
private:
friend struct base::DefaultSingletonTraits<ProtoDatabaseProviderFactory>;
ProtoDatabaseProviderFactory();
~ProtoDatabaseProviderFactory() override;
// BrowserContextKeyedServiceFactory overrides:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
DISALLOW_COPY_AND_ASSIGN(ProtoDatabaseProviderFactory);
};
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_CONTENT_PROTO_DATABASE_PROVIDER_FACTORY_H_
...@@ -138,6 +138,14 @@ bool LevelDB::Save(const base::StringPairs& entries_to_save, ...@@ -138,6 +138,14 @@ bool LevelDB::Save(const base::StringPairs& entries_to_save,
bool LevelDB::UpdateWithRemoveFilter(const base::StringPairs& entries_to_save, bool LevelDB::UpdateWithRemoveFilter(const base::StringPairs& entries_to_save,
const KeyFilter& delete_key_filter, const KeyFilter& delete_key_filter,
leveldb::Status* status) { leveldb::Status* status) {
return UpdateWithRemoveFilter(entries_to_save, delete_key_filter,
std::string(), status);
}
bool LevelDB::UpdateWithRemoveFilter(const base::StringPairs& entries_to_save,
const KeyFilter& delete_key_filter,
const std::string& target_prefix,
leveldb::Status* status) {
DCHECK(status); DCHECK(status);
DFAKE_SCOPED_LOCK(thread_checker_); DFAKE_SCOPED_LOCK(thread_checker_);
if (!db_) if (!db_)
...@@ -147,11 +155,13 @@ bool LevelDB::UpdateWithRemoveFilter(const base::StringPairs& entries_to_save, ...@@ -147,11 +155,13 @@ bool LevelDB::UpdateWithRemoveFilter(const base::StringPairs& entries_to_save,
for (const auto& pair : entries_to_save) for (const auto& pair : entries_to_save)
updates.Put(leveldb::Slice(pair.first), leveldb::Slice(pair.second)); updates.Put(leveldb::Slice(pair.first), leveldb::Slice(pair.second));
leveldb::Slice target(target_prefix);
if (!delete_key_filter.is_null()) { if (!delete_key_filter.is_null()) {
leveldb::ReadOptions read_options; leveldb::ReadOptions read_options;
std::unique_ptr<leveldb::Iterator> db_iterator( std::unique_ptr<leveldb::Iterator> db_iterator(
db_->NewIterator(read_options)); db_->NewIterator(read_options));
for (db_iterator->SeekToFirst(); db_iterator->Valid(); for (db_iterator->Seek(target);
db_iterator->Valid() && db_iterator->key().starts_with(target);
db_iterator->Next()) { db_iterator->Next()) {
leveldb::Slice key_slice = db_iterator->key(); leveldb::Slice key_slice = db_iterator->key();
std::string key(key_slice.data(), key_slice.size()); std::string key(key_slice.data(), key_slice.size());
...@@ -235,11 +245,16 @@ bool LevelDB::LoadKeysAndEntriesWithFilter( ...@@ -235,11 +245,16 @@ bool LevelDB::LoadKeysAndEntriesWithFilter(
} }
bool LevelDB::LoadKeys(std::vector<std::string>* keys) { bool LevelDB::LoadKeys(std::vector<std::string>* keys) {
return LoadKeys(std::string(), keys);
}
bool LevelDB::LoadKeys(const std::string& target_prefix,
std::vector<std::string>* keys) {
leveldb::ReadOptions options; leveldb::ReadOptions options;
options.fill_cache = false; options.fill_cache = false;
std::map<std::string, std::string> keys_entries; std::map<std::string, std::string> keys_entries;
bool result = LoadKeysAndEntriesWithFilter(KeyFilter(), &keys_entries, bool result = LoadKeysAndEntriesWithFilter(KeyFilter(), &keys_entries,
options, std::string()); options, target_prefix);
if (!result) if (!result)
return false; return false;
......
...@@ -51,9 +51,14 @@ class LevelDB { ...@@ -51,9 +51,14 @@ class LevelDB {
virtual bool Save(const base::StringPairs& pairs_to_save, virtual bool Save(const base::StringPairs& pairs_to_save,
const std::vector<std::string>& keys_to_remove, const std::vector<std::string>& keys_to_remove,
leveldb::Status* status); leveldb::Status* status);
virtual bool UpdateWithRemoveFilter(const base::StringPairs& entries_to_save, virtual bool UpdateWithRemoveFilter(const base::StringPairs& entries_to_save,
const KeyFilter& delete_key_filter, const KeyFilter& delete_key_filter,
leveldb::Status* status); leveldb::Status* status);
virtual bool UpdateWithRemoveFilter(const base::StringPairs& entries_to_save,
const KeyFilter& delete_key_filter,
const std::string& target_prefix,
leveldb::Status* status);
virtual bool Load(std::vector<std::string>* entries); virtual bool Load(std::vector<std::string>* entries);
virtual bool LoadWithFilter(const KeyFilter& filter, virtual bool LoadWithFilter(const KeyFilter& filter,
...@@ -75,6 +80,9 @@ class LevelDB { ...@@ -75,6 +80,9 @@ class LevelDB {
const std::string& target_prefix); const std::string& target_prefix);
virtual bool LoadKeys(std::vector<std::string>* keys); virtual bool LoadKeys(std::vector<std::string>* keys);
virtual bool LoadKeys(const std::string& target_prefix,
std::vector<std::string>* keys);
virtual bool Get(const std::string& key, virtual bool Get(const std::string& key,
bool* found, bool* found,
std::string* entry, std::string* entry,
......
...@@ -37,29 +37,22 @@ class ProtoDatabase { ...@@ -37,29 +37,22 @@ class ProtoDatabase {
// A list of key-value (string, T) tuples. // A list of key-value (string, T) tuples.
using KeyEntryVector = std::vector<std::pair<std::string, T>>; using KeyEntryVector = std::vector<std::pair<std::string, T>>;
explicit ProtoDatabase( virtual ~ProtoDatabase() = default;
const scoped_refptr<base::SequencedTaskRunner>& task_runner)
: db_wrapper_(std::make_unique<ProtoLevelDBWrapper>(task_runner)) {}
virtual ~ProtoDatabase() {}
// Asynchronously initializes the object with the specified |options|. // Asynchronously initializes the object with the specified |options|.
// |callback| will be invoked on the calling thread when complete. // |callback| will be invoked on the calling thread when complete.
virtual void Init(const std::string& client_name, virtual void Init(const std::string& client_name, InitCallback callback) = 0;
typename ProtoDatabase<T>::InitCallback callback) = 0;
// This version of Init is for compatibility, since many of the current // This version of Init is for compatibility, since many of the current
// proto database clients still use this. // proto database clients still use this.
virtual void Init(const char* client_name, virtual void Init(const char* client_name,
const base::FilePath& database_dir, const base::FilePath& database_dir,
const leveldb_env::Options& options, const leveldb_env::Options& options,
typename ProtoDatabase<T>::InitCallback callback) = 0; InitCallback callback) = 0;
virtual void InitWithDatabase(LevelDB* database, virtual void InitWithDatabase(LevelDB* database,
const base::FilePath& database_dir, const base::FilePath& database_dir,
const leveldb_env::Options& options, const leveldb_env::Options& options,
InitCallback callback) { InitCallback callback) = 0;
db_wrapper_->InitWithDatabase(database, database_dir, options,
std::move(callback));
}
// Asynchronously saves |entries_to_save| and deletes entries from // Asynchronously saves |entries_to_save| and deletes entries from
// |keys_to_remove| from the database. |callback| will be invoked on the // |keys_to_remove| from the database. |callback| will be invoked on the
...@@ -67,11 +60,7 @@ class ProtoDatabase { ...@@ -67,11 +60,7 @@ class ProtoDatabase {
virtual void UpdateEntries( virtual void UpdateEntries(
std::unique_ptr<KeyEntryVector> entries_to_save, std::unique_ptr<KeyEntryVector> entries_to_save,
std::unique_ptr<std::vector<std::string>> keys_to_remove, std::unique_ptr<std::vector<std::string>> keys_to_remove,
UpdateCallback callback) { UpdateCallback callback) = 0;
db_wrapper_->template UpdateEntries<T>(std::move(entries_to_save),
std::move(keys_to_remove),
std::move(callback));
}
// Asynchronously saves |entries_to_save| and deletes entries that satisfies // Asynchronously saves |entries_to_save| and deletes entries that satisfies
// the |delete_key_filter| from the database. |callback| will be invoked on // the |delete_key_filter| from the database. |callback| will be invoked on
...@@ -80,76 +69,54 @@ class ProtoDatabase { ...@@ -80,76 +69,54 @@ class ProtoDatabase {
virtual void UpdateEntriesWithRemoveFilter( virtual void UpdateEntriesWithRemoveFilter(
std::unique_ptr<KeyEntryVector> entries_to_save, std::unique_ptr<KeyEntryVector> entries_to_save,
const LevelDB::KeyFilter& delete_key_filter, const LevelDB::KeyFilter& delete_key_filter,
UpdateCallback callback) { UpdateCallback callback) = 0;
db_wrapper_->template UpdateEntriesWithRemoveFilter<T>( virtual void UpdateEntriesWithRemoveFilter(
std::move(entries_to_save), delete_key_filter, std::move(callback)); std::unique_ptr<KeyEntryVector> entries_to_save,
} const LevelDB::KeyFilter& delete_key_filter,
const std::string& target_prefix,
UpdateCallback callback) = 0;
// Asynchronously loads all entries from the database and invokes |callback| // Asynchronously loads all entries from the database and invokes |callback|
// when complete. // when complete.
virtual void LoadEntries(LoadCallback callback) { virtual void LoadEntries(LoadCallback callback) = 0;
db_wrapper_->template LoadEntries<T>(std::move(callback));
}
// Asynchronously loads entries that satisfies the |filter| from the database // Asynchronously loads entries that satisfies the |filter| from the database
// and invokes |callback| when complete. The filter will be called on // and invokes |callback| when complete. The filter will be called on
// ProtoDatabase's taskrunner. // ProtoDatabase's taskrunner.
virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& filter, virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& filter,
LoadCallback callback) { LoadCallback callback) = 0;
db_wrapper_->template LoadEntriesWithFilter<T>(filter, std::move(callback));
}
virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& key_filter, virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& key_filter,
const leveldb::ReadOptions& options, const leveldb::ReadOptions& options,
const std::string& target_prefix, const std::string& target_prefix,
LoadCallback callback) { LoadCallback callback) = 0;
db_wrapper_->template LoadEntriesWithFilter<T>(
key_filter, options, target_prefix, std::move(callback));
}
virtual void LoadKeysAndEntries(LoadKeysAndEntriesCallback callback) { virtual void LoadKeysAndEntries(LoadKeysAndEntriesCallback callback) = 0;
db_wrapper_->template LoadKeysAndEntries<T>(std::move(callback));
}
virtual void LoadKeysAndEntriesWithFilter( virtual void LoadKeysAndEntriesWithFilter(
const LevelDB::KeyFilter& filter, const LevelDB::KeyFilter& filter,
typename ProtoDatabase<T>::LoadKeysAndEntriesCallback callback) { LoadKeysAndEntriesCallback callback) = 0;
db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(filter,
std::move(callback));
}
virtual void LoadKeysAndEntriesWithFilter( virtual void LoadKeysAndEntriesWithFilter(
const LevelDB::KeyFilter& filter, const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options, const leveldb::ReadOptions& options,
const std::string& target_prefix, const std::string& target_prefix,
typename ProtoDatabase<T>::LoadKeysAndEntriesCallback callback) { LoadKeysAndEntriesCallback callback) = 0;
db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(
filter, options, target_prefix, std::move(callback));
}
// Asynchronously loads all keys from the database and invokes |callback| with // Asynchronously loads all keys from the database and invokes |callback| with
// those keys when complete. // those keys when complete.
virtual void LoadKeys(LoadKeysCallback callback) { virtual void LoadKeys(LoadKeysCallback callback) = 0;
db_wrapper_->LoadKeys(std::move(callback)); virtual void LoadKeys(const std::string& target_prefix,
} LoadKeysCallback callback) = 0;
// Asynchronously loads a single entry, identified by |key|, from the database // Asynchronously loads a single entry, identified by |key|, from the database
// and invokes |callback| when complete. If no entry with |key| is found, // and invokes |callback| when complete. If no entry with |key| is found,
// a nullptr is passed to the callback, but the success flag is still true. // a nullptr is passed to the callback, but the success flag is still true.
virtual void GetEntry(const std::string& key, GetCallback callback) { virtual void GetEntry(const std::string& key, GetCallback callback) = 0;
db_wrapper_->template GetEntry<T>(key, std::move(callback));
}
// Asynchronously destroys the database. // Asynchronously destroys the database.
virtual void Destroy(DestroyCallback callback) { virtual void Destroy(DestroyCallback callback) = 0;
db_wrapper_->Destroy(std::move(callback));
}
bool GetApproximateMemoryUse(uint64_t* approx_mem_use) {
return db_wrapper_->GetApproximateMemoryUse(approx_mem_use);
}
protected: protected:
std::unique_ptr<ProtoLevelDBWrapper> db_wrapper_; ProtoDatabase() = default;
}; };
// Return a new instance of Options, but with two additions: // Return a new instance of Options, but with two additions:
......
// Copyright 2018 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.
#include "components/leveldb_proto/proto_database_provider.h"
#include "base/files/file_path.h"
namespace leveldb_proto {
ProtoDatabaseProvider::ProtoDatabaseProvider(const base::FilePath& profile_dir)
: profile_dir_(profile_dir) {}
// static
ProtoDatabaseProvider* ProtoDatabaseProvider::Create(
const base::FilePath& profile_dir) {
return new ProtoDatabaseProvider(profile_dir);
}
} // namespace leveldb_proto
// Copyright 2018 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_LEVELDB_PROTO_PROTO_DATABASE_PROVIDER_H_
#define COMPONENTS_LEVELDB_PROTO_PROTO_DATABASE_PROVIDER_H_
#include "base/files/file_path.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/leveldb_proto/proto_database.h"
#include "components/leveldb_proto/proto_database_wrapper.h"
namespace leveldb_proto {
// A KeyedService that provides instances of ProtoDatabase tied to the current
// profile directory.
class ProtoDatabaseProvider : public KeyedService {
public:
static ProtoDatabaseProvider* Create(const base::FilePath& profile_dir);
// |unique_db_dir|: the subdirectory this database should live in within
// the profile directory.
// |task_runner|: the SequencedTaskRunner to run all database operations on.
template <typename T>
std::unique_ptr<ProtoDatabase<T>> GetDB(
const base::FilePath& unique_db_dir,
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
~ProtoDatabaseProvider() override = default;
private:
ProtoDatabaseProvider(const base::FilePath& profile_dir);
base::FilePath profile_dir_;
};
template <typename T>
std::unique_ptr<ProtoDatabase<T>> ProtoDatabaseProvider::GetDB(
const base::FilePath& unique_db_dir,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
return std::make_unique<ProtoDatabaseWrapper<T>>(unique_db_dir, task_runner);
}
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_PROTO_DATABASE_PROVIDER_H_
\ No newline at end of file
This diff is collapsed.
...@@ -51,6 +51,7 @@ void RunLoadKeysCallback( ...@@ -51,6 +51,7 @@ void RunLoadKeysCallback(
} }
inline void LoadKeysFromTaskRunner(LevelDB* database, inline void LoadKeysFromTaskRunner(LevelDB* database,
const std::string& target_prefix,
std::vector<std::string>* keys, std::vector<std::string>* keys,
bool* success, bool* success,
const std::string& client_id) { const std::string& client_id) {
...@@ -67,25 +68,28 @@ ProtoLevelDBWrapper::ProtoLevelDBWrapper( ...@@ -67,25 +68,28 @@ ProtoLevelDBWrapper::ProtoLevelDBWrapper(
const scoped_refptr<base::SequencedTaskRunner>& task_runner) const scoped_refptr<base::SequencedTaskRunner>& task_runner)
: task_runner_(task_runner) {} : task_runner_(task_runner) {}
ProtoLevelDBWrapper::ProtoLevelDBWrapper(
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
LevelDB* db)
: task_runner_(task_runner), db_(db) {}
ProtoLevelDBWrapper::~ProtoLevelDBWrapper() = default; ProtoLevelDBWrapper::~ProtoLevelDBWrapper() = default;
void ProtoLevelDBWrapper::InitWithDatabase( void ProtoLevelDBWrapper::InitWithDatabase(
LevelDB* database, LevelDB* database,
const base::FilePath& database_dir, const base::FilePath& database_dir,
const leveldb_env::Options& options, const leveldb_env::Options& options,
bool destroy_on_corruption,
typename ProtoLevelDBWrapper::InitCallback callback) { typename ProtoLevelDBWrapper::InitCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!db_); DCHECK(!db_);
DCHECK(database); DCHECK(database);
db_ = database; db_ = database;
leveldb::Status* status = new leveldb::Status(); leveldb::Status* status = new leveldb::Status();
// Sets |destroy_on_corruption| to true to mimic the original behaviour for
// now.
task_runner_->PostTaskAndReply( task_runner_->PostTaskAndReply(
FROM_HERE, FROM_HERE,
base::BindOnce(InitFromTaskRunner, base::Unretained(db_), database_dir, base::BindOnce(InitFromTaskRunner, base::Unretained(db_), database_dir,
options, true /* destroy_on_corruption */, status, options, destroy_on_corruption, status, metrics_id_),
metrics_id_),
base::BindOnce(RunInitCallback, std::move(callback), base::BindOnce(RunInitCallback, std::move(callback),
base::Owned(status))); base::Owned(status)));
} }
...@@ -106,13 +110,22 @@ void ProtoLevelDBWrapper::Destroy( ...@@ -106,13 +110,22 @@ void ProtoLevelDBWrapper::Destroy(
void ProtoLevelDBWrapper::LoadKeys( void ProtoLevelDBWrapper::LoadKeys(
typename ProtoLevelDBWrapper::LoadKeysCallback callback) { typename ProtoLevelDBWrapper::LoadKeysCallback callback) {
LoadKeys(std::string(), std::move(callback));
}
void ProtoLevelDBWrapper::LoadKeys(
const std::string& target_prefix,
typename ProtoLevelDBWrapper::LoadKeysCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto success = std::make_unique<bool>(false); auto success = std::make_unique<bool>(false);
auto keys = std::make_unique<std::vector<std::string>>(); auto keys = std::make_unique<std::vector<std::string>>();
auto load_task = base::BindOnce(LoadKeysFromTaskRunner, base::Unretained(db_), bool* success_ptr = success.get();
keys.get(), success.get(), metrics_id_); std::vector<std::string>* keys_ptr = keys.get();
task_runner_->PostTaskAndReply( task_runner_->PostTaskAndReply(
FROM_HERE, std::move(load_task), FROM_HERE,
base::BindOnce(LoadKeysFromTaskRunner, base::Unretained(db_),
target_prefix, base::Unretained(keys_ptr),
base::Unretained(success_ptr), metrics_id_),
base::BindOnce(RunLoadKeysCallback, std::move(callback), base::BindOnce(RunLoadKeysCallback, std::move(callback),
std::move(success), std::move(keys))); std::move(success), std::move(keys)));
} }
......
...@@ -60,6 +60,10 @@ class ProtoLevelDBWrapper { ...@@ -60,6 +60,10 @@ class ProtoLevelDBWrapper {
ProtoLevelDBWrapper( ProtoLevelDBWrapper(
const scoped_refptr<base::SequencedTaskRunner>& task_runner); const scoped_refptr<base::SequencedTaskRunner>& task_runner);
ProtoLevelDBWrapper(
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
LevelDB* db);
virtual ~ProtoLevelDBWrapper(); virtual ~ProtoLevelDBWrapper();
template <typename T> template <typename T>
...@@ -76,6 +80,14 @@ class ProtoLevelDBWrapper { ...@@ -76,6 +80,14 @@ class ProtoLevelDBWrapper {
const LevelDB::KeyFilter& delete_key_filter, const LevelDB::KeyFilter& delete_key_filter,
UpdateCallback callback); UpdateCallback callback);
template <typename T>
void UpdateEntriesWithRemoveFilter(
std::unique_ptr<typename ProtoLevelDBWrapper::Internal<T>::KeyEntryVector>
entries_to_save,
const LevelDB::KeyFilter& delete_key_filter,
const std::string& target_prefix,
UpdateCallback callback);
template <typename T> template <typename T>
void LoadEntries( void LoadEntries(
typename ProtoLevelDBWrapper::Internal<T>::LoadCallback callback); typename ProtoLevelDBWrapper::Internal<T>::LoadCallback callback);
...@@ -112,6 +124,7 @@ class ProtoLevelDBWrapper { ...@@ -112,6 +124,7 @@ class ProtoLevelDBWrapper {
callback); callback);
void LoadKeys(LoadKeysCallback callback); void LoadKeys(LoadKeysCallback callback);
void LoadKeys(const std::string& target_prefix, LoadKeysCallback callback);
template <typename T> template <typename T>
void GetEntry( void GetEntry(
...@@ -124,6 +137,7 @@ class ProtoLevelDBWrapper { ...@@ -124,6 +137,7 @@ class ProtoLevelDBWrapper {
void InitWithDatabase(LevelDB* database, void InitWithDatabase(LevelDB* database,
const base::FilePath& database_dir, const base::FilePath& database_dir,
const leveldb_env::Options& options, const leveldb_env::Options& options,
bool destroy_on_corruption,
InitCallback callback); InitCallback callback);
void SetMetricsId(const std::string& id); void SetMetricsId(const std::string& id);
...@@ -334,6 +348,18 @@ void ProtoLevelDBWrapper::UpdateEntriesWithRemoveFilter( ...@@ -334,6 +348,18 @@ void ProtoLevelDBWrapper::UpdateEntriesWithRemoveFilter(
entries_to_save, entries_to_save,
const LevelDB::KeyFilter& delete_key_filter, const LevelDB::KeyFilter& delete_key_filter,
typename ProtoLevelDBWrapper::UpdateCallback callback) { typename ProtoLevelDBWrapper::UpdateCallback callback) {
UpdateEntriesWithRemoveFilter<T>(std::move(entries_to_save),
delete_key_filter, std::string(),
std::move(callback));
}
template <typename T>
void ProtoLevelDBWrapper::UpdateEntriesWithRemoveFilter(
std::unique_ptr<typename ProtoLevelDBWrapper::Internal<T>::KeyEntryVector>
entries_to_save,
const LevelDB::KeyFilter& delete_key_filter,
const std::string& target_prefix,
typename ProtoLevelDBWrapper::UpdateCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
bool* success = new bool(false); bool* success = new bool(false);
task_runner_->PostTaskAndReply( task_runner_->PostTaskAndReply(
......
...@@ -29,9 +29,10 @@ class FakeDB : public UniqueProtoDatabase<T> { ...@@ -29,9 +29,10 @@ class FakeDB : public UniqueProtoDatabase<T> {
using EntryMap = std::map<std::string, T>; using EntryMap = std::map<std::string, T>;
explicit FakeDB(EntryMap* db); explicit FakeDB(EntryMap* db);
~FakeDB() override;
// ProtoDatabase implementation. // ProtoDatabase implementation.
void Init(const std::string& client_name,
typename ProtoDatabase<T>::InitCallback callback) override;
void Init(const char* client_name, void Init(const char* client_name,
const base::FilePath& database_dir, const base::FilePath& database_dir,
const leveldb_env::Options& options, const leveldb_env::Options& options,
...@@ -128,7 +129,11 @@ FakeDB<T>::FakeDB(EntryMap* db) ...@@ -128,7 +129,11 @@ FakeDB<T>::FakeDB(EntryMap* db)
} }
template <typename T> template <typename T>
FakeDB<T>::~FakeDB() {} void FakeDB<T>::Init(const std::string& client_name,
typename ProtoDatabase<T>::InitCallback callback) {
Init(client_name.c_str(), base::FilePath(FILE_PATH_LITERAL("db_dir")),
leveldb_proto::CreateSimpleOptions(), std::move(callback));
}
template <typename T> template <typename T>
void FakeDB<T>::Init(const char* client_name, void FakeDB<T>::Init(const char* client_name,
......
...@@ -19,8 +19,10 @@ source_set("feature_engagement") { ...@@ -19,8 +19,10 @@ source_set("feature_engagement") {
"//components/feature_engagement", "//components/feature_engagement",
"//components/keyed_service/core", "//components/keyed_service/core",
"//components/keyed_service/ios", "//components/keyed_service/ios",
"//components/leveldb_proto",
"//ios/chrome/browser", "//ios/chrome/browser",
"//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state",
"//ios/chrome/browser/leveldb_proto:factory",
"//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/commands",
"//ios/web/public", "//ios/web/public",
] ]
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "components/feature_engagement/public/tracker.h" #include "components/feature_engagement/public/tracker.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/chrome_constants.h" #include "ios/chrome/browser/chrome_constants.h"
#include "ios/chrome/browser/leveldb_proto/proto_database_provider_factory.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -38,8 +39,12 @@ std::unique_ptr<KeyedService> CreateFeatureEngagementTracker( ...@@ -38,8 +39,12 @@ std::unique_ptr<KeyedService> CreateFeatureEngagementTracker(
base::FilePath storage_dir = browser_state->GetStatePath().Append( base::FilePath storage_dir = browser_state->GetStatePath().Append(
kIOSFeatureEngagementTrackerStorageDirname); kIOSFeatureEngagementTrackerStorageDirname);
return base::WrapUnique( leveldb_proto::ProtoDatabaseProvider* db_provider =
feature_engagement::Tracker::Create(storage_dir, background_task_runner)); leveldb_proto::ProtoDatabaseProviderFactory::GetForBrowserState(
browser_state);
return base::WrapUnique(feature_engagement::Tracker::Create(
storage_dir, background_task_runner, db_provider));
} }
} // namespace feature_engagement } // namespace feature_engagement
# Copyright 2018 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.
source_set("factory") {
sources = [
"proto_database_provider_factory.h",
"proto_database_provider_factory.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
"//base",
"//components/keyed_service/core",
"//components/keyed_service/ios",
"//components/leveldb_proto",
"//ios/chrome/browser",
"//ios/chrome/browser/browser_state",
]
}
// Copyright 2018 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 IOS_CHROME_BROWSER_LEVELDB_PROTO_PROTO_DATABASE_PROVIDER_FACTORY_H_
#define IOS_CHROME_BROWSER_LEVELDB_PROTO_PROTO_DATABASE_PROVIDER_FACTORY_H_
#include "base/macros.h"
#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
namespace base {
template <typename T>
struct DefaultSingletonTraits;
} // namespace base
namespace ios {
class ChromeBrowserState;
} // namespace ios
namespace leveldb_proto {
class ProtoDatabaseProvider;
// A factory for ProtoDatabaseProvider, a class that provides proto databases
// stored in the appropriate directory given an ios::ChromeBrowserState object.
class ProtoDatabaseProviderFactory : public BrowserStateKeyedServiceFactory {
public:
// Returns singleton instance of ProtoDatabaseProviderFactory.
static ProtoDatabaseProviderFactory* GetInstance();
// Returns ProtoDatabaseProvider associated with |context|, so we can
// instantiate ProtoDatabases that use the appropriate profile directory.
static ProtoDatabaseProvider* GetForBrowserState(
ios::ChromeBrowserState* browser_state);
protected:
// BrowserStateKeyedServiceFactory implementation.
std::unique_ptr<KeyedService> BuildServiceInstanceFor(
web::BrowserState* context) const override;
private:
friend struct base::DefaultSingletonTraits<ProtoDatabaseProviderFactory>;
ProtoDatabaseProviderFactory();
~ProtoDatabaseProviderFactory() override;
DISALLOW_COPY_AND_ASSIGN(ProtoDatabaseProviderFactory);
};
} // namespace leveldb_proto
#endif // IOS_CHROME_BROWSER_LEVELDB_PROTO_PROTO_DATABASE_PROVIDER_FACTORY_H_
\ No newline at end of file
// Copyright 2018 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.
#include "ios/chrome/browser/leveldb_proto/proto_database_provider_factory.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/ios/browser_state_dependency_manager.h"
#include "components/leveldb_proto/proto_database_provider.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace leveldb_proto {
// static
ProtoDatabaseProviderFactory* ProtoDatabaseProviderFactory::GetInstance() {
return base::Singleton<ProtoDatabaseProviderFactory>::get();
}
// static
leveldb_proto::ProtoDatabaseProvider*
ProtoDatabaseProviderFactory::GetForBrowserState(
ios::ChromeBrowserState* browser_state) {
return static_cast<leveldb_proto::ProtoDatabaseProvider*>(
GetInstance()->GetServiceForBrowserState(browser_state, true));
}
ProtoDatabaseProviderFactory::ProtoDatabaseProviderFactory()
: BrowserStateKeyedServiceFactory(
"leveldb_proto::ProtoDatabaseProvider",
BrowserStateDependencyManager::GetInstance()) {}
ProtoDatabaseProviderFactory::~ProtoDatabaseProviderFactory() = default;
std::unique_ptr<KeyedService>
ProtoDatabaseProviderFactory::BuildServiceInstanceFor(
web::BrowserState* context) const {
base::FilePath profile_dir = context->GetStatePath();
return base::WrapUnique(
leveldb_proto::ProtoDatabaseProvider::Create(profile_dir));
}
} // namespace leveldb_proto
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment