blob: 1e2b872fa22001a6cc695beb1e337b938fb49c1e [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_DATABASE_STORAGE_SERVICE_H_
#define COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_DATABASE_STORAGE_SERVICE_H_
#include <memory>
#include <optional>
#include "base/check.h"
#include "base/containers/flat_set.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/leveldb_proto/public/proto_database.h"
#include "components/segmentation_platform/internal/database/cached_result_provider.h"
#include "components/segmentation_platform/internal/database/cached_result_writer.h"
#include "components/segmentation_platform/internal/database/client_result_prefs.h"
#include "components/segmentation_platform/internal/database/config_holder.h"
#include "components/segmentation_platform/internal/execution/model_manager.h"
#include "components/segmentation_platform/internal/execution/model_manager_impl.h"
#include "components/segmentation_platform/public/proto/segmentation_platform.pb.h"
class PrefService;
namespace base {
class Clock;
class FilePath;
class SequencedTaskRunner;
} // namespace base
namespace leveldb_proto {
class ProtoDatabaseProvider;
} // namespace leveldb_proto
namespace segmentation_platform {
namespace proto {
class SegmentInfo;
class SignalData;
class SignalStorageConfigs;
} // namespace proto
class DatabaseMaintenanceImpl;
class ModelManager;
class ModelProviderFactory;
class SegmentInfoDatabase;
class SignalDatabase;
class SignalStorageConfig;
class UkmDataManager;
// Qualifiers used to indicate service status. One or more qualifiers can
// be used at a time.
enum class ServiceStatus {
// Server not yet initialized.
kUninitialized = 0,
// Segmentation information DB is initialized.
kSegmentationInfoDbInitialized = 1,
// Signal database is initialized.
kSignalDbInitialized = 1 << 1,
// Signal storage config is initialized.
kSignalStorageConfigInitialized = 1 << 2,
};
// Owns and manages all the storage databases for the platform.
class StorageService {
public:
StorageService(
const base::FilePath& storage_dir,
leveldb_proto::ProtoDatabaseProvider* db_provider,
scoped_refptr<base::SequencedTaskRunner> task_runner,
base::Clock* clock,
UkmDataManager* ukm_data_manager,
std::vector<std::unique_ptr<Config>> configs,
ModelProviderFactory* model_provider_factory,
PrefService* profile_prefs,
const std::string& profile_id,
ModelManager::SegmentationModelUpdatedCallback model_updated_callback);
// For tests:
StorageService(
std::unique_ptr<leveldb_proto::ProtoDatabase<proto::SegmentInfo>>
segment_db,
std::unique_ptr<leveldb_proto::ProtoDatabase<proto::SignalData>>
signal_db,
std::unique_ptr<leveldb_proto::ProtoDatabase<proto::SignalStorageConfigs>>
signal_storage_config_db,
scoped_refptr<base::SequencedTaskRunner> task_runner,
base::Clock* clock,
UkmDataManager* ukm_data_manager,
std::vector<std::unique_ptr<Config>> configs,
ModelProviderFactory* model_provider_factory,
PrefService* profile_prefs,
const std::string& profile_id,
ModelManager::SegmentationModelUpdatedCallback model_updated_callback);
// For tests:
StorageService(std::unique_ptr<SegmentInfoDatabase> segment_info_database,
std::unique_ptr<SignalDatabase> signal_database,
std::unique_ptr<SignalStorageConfig> signal_storage_config,
std::unique_ptr<ModelManager> model_manager,
std::unique_ptr<ConfigHolder> config_holder,
UkmDataManager* ukm_data_manager);
~StorageService();
StorageService(const StorageService&) = delete;
StorageService& operator=(const StorageService&) = delete;
// Initialize all the databases and returns true when all of them are
// initialized successfully.
using SuccessCallback = base::OnceCallback<void(bool)>;
void Initialize(SuccessCallback callback);
// Returns a bitmap of the service status. See `ServiceStatus` enum for the
// bitmap values.
int GetServiceStatus() const;
// Executes all database maintenance tasks.
void ExecuteDatabaseMaintenanceTasks(bool is_startup);
const ConfigHolder* config_holder() const { return config_holder_.get(); }
CachedResultProvider* cached_result_provider() {
return cached_result_provider_.get();
}
CachedResultWriter* cached_result_writer() {
return cached_result_writer_.get();
}
ModelManager* model_manager() {
DCHECK(model_manager_);
return model_manager_.get();
}
SegmentInfoDatabase* segment_info_database() {
return segment_info_database_.get();
}
SignalDatabase* signal_database() { return signal_database_.get(); }
SignalStorageConfig* signal_storage_config() {
return signal_storage_config_.get();
}
UkmDataManager* ukm_data_manager() { return ukm_data_manager_; }
const std::string& profile_id() const { return profile_id_; }
ClientResultPrefs* client_result_prefs() {
return client_result_prefs_.get();
}
void set_cached_result_writer_for_testing(
std::unique_ptr<CachedResultWriter> writer) {
cached_result_writer_ = std::move(writer);
}
void set_cached_result_provider_for_testing(
std::unique_ptr<CachedResultProvider> provider) {
cached_result_provider_ = std::move(provider);
}
void set_profile_id_for_testing(const std::string& profile_id) {
profile_id_ = profile_id;
}
// Get a WeakPtr to the service. Feature processors are destroyed after
// service sometimes due to posted tasks. WeakPtr is useful to refer to the
// service.
base::WeakPtr<StorageService> GetWeakPtr();
private:
void OnSegmentInfoDatabaseInitialized(bool success);
void OnSignalDatabaseInitialized(bool success);
void OnSignalStorageConfigInitialized(bool success);
bool IsInitializationFinished() const;
void MaybeFinishInitialization();
// All client Configs.
std::unique_ptr<ConfigHolder> config_holder_;
std::unique_ptr<ClientResultPrefs> client_result_prefs_;
// Result cache.
std::unique_ptr<CachedResultProvider> cached_result_provider_;
// Writes to result cache.
std::unique_ptr<CachedResultWriter> cached_result_writer_;
// Databases.
std::unique_ptr<SegmentInfoDatabase> segment_info_database_;
std::unique_ptr<SignalDatabase> signal_database_;
std::unique_ptr<SignalStorageConfig> signal_storage_config_;
// Provides provider for default and server models.
std::unique_ptr<ModelManager> model_manager_;
// The data manager is owned by the database client and is guaranteed to be
// kept alive until all profiles (keyed services) are destroyed. Refer to the
// description of UkmDataManager to know the lifetime of the objects usable
// from the manager.
raw_ptr<UkmDataManager> ukm_data_manager_;
// The profile ID of the current profile, used to query the UKM database.
std::string profile_id_;
// Database maintenance.
std::unique_ptr<DatabaseMaintenanceImpl> database_maintenance_;
// Database initialization statuses.
std::optional<bool> segment_info_database_initialized_;
std::optional<bool> signal_database_initialized_;
std::optional<bool> signal_storage_config_initialized_;
SuccessCallback init_callback_;
base::WeakPtrFactory<StorageService> weak_ptr_factory_{this};
};
} // namespace segmentation_platform
#endif // COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_DATABASE_STORAGE_SERVICE_H_