blob: 4360410d332b871a04fca43042132478fd1424b0 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/prefs/wrap_with_prefix_pref_store.h"
#include <string>
#include <string_view>
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
WrapWithPrefixPrefStore::WrapWithPrefixPrefStore(
scoped_refptr<PersistentPrefStore> target_pref_store,
std::string_view path_prefix)
: target_pref_store_(std::move(target_pref_store)),
dotted_prefix_(base::StrCat({path_prefix, "."})) {
target_pref_store_->AddObserver(this);
}
WrapWithPrefixPrefStore::~WrapWithPrefixPrefStore() {
target_pref_store_->RemoveObserver(this);
}
bool WrapWithPrefixPrefStore::GetValue(std::string_view key,
const base::Value** value) const {
return target_pref_store_->GetValue(AddDottedPrefix(key), value);
}
base::Value::Dict WrapWithPrefixPrefStore::GetValues() const {
base::Value::Dict values = target_pref_store_->GetValues();
std::string_view prefix(dotted_prefix_.c_str(), dotted_prefix_.size() - 1);
if (base::Value::Dict* values_with_prefix =
values.FindDictByDottedPath(prefix)) {
return std::move(*values_with_prefix);
}
return {};
}
bool WrapWithPrefixPrefStore::GetMutableValue(std::string_view key,
base::Value** value) {
return target_pref_store_->GetMutableValue(AddDottedPrefix(key), value);
}
void WrapWithPrefixPrefStore::AddObserver(PrefStore::Observer* observer) {
observers_.AddObserver(observer);
}
void WrapWithPrefixPrefStore::RemoveObserver(PrefStore::Observer* observer) {
observers_.RemoveObserver(observer);
}
bool WrapWithPrefixPrefStore::HasObservers() const {
return !observers_.empty();
}
bool WrapWithPrefixPrefStore::IsInitializationComplete() const {
return target_pref_store_->IsInitializationComplete();
}
void WrapWithPrefixPrefStore::SetValue(std::string_view key,
base::Value value,
uint32_t flags) {
target_pref_store_->SetValue(AddDottedPrefix(key), std::move(value), flags);
}
void WrapWithPrefixPrefStore::SetValueSilently(std::string_view key,
base::Value value,
uint32_t flags) {
target_pref_store_->SetValueSilently(AddDottedPrefix(key), std::move(value),
flags);
}
void WrapWithPrefixPrefStore::RemoveValue(std::string_view key,
uint32_t flags) {
target_pref_store_->RemoveValue(AddDottedPrefix(key), flags);
}
void WrapWithPrefixPrefStore::RemoveValuesByPrefixSilently(
std::string_view prefix) {
target_pref_store_->RemoveValuesByPrefixSilently(AddDottedPrefix(prefix));
}
bool WrapWithPrefixPrefStore::ReadOnly() const {
return target_pref_store_->ReadOnly();
}
PersistentPrefStore::PrefReadError WrapWithPrefixPrefStore::GetReadError()
const {
return target_pref_store_->GetReadError();
}
PersistentPrefStore::PrefReadError WrapWithPrefixPrefStore::ReadPrefs() {
// The target pref store should have been initialized prior to calling
// ReadPrefs() on this store.
CHECK(target_pref_store_->IsInitializationComplete() ||
// To catch case where target pref store initialization failed.
target_pref_store_->GetReadError() !=
PersistentPrefStore::PREF_READ_ERROR_NONE);
return target_pref_store_->GetReadError();
}
void WrapWithPrefixPrefStore::ReadPrefsAsync(
ReadErrorDelegate* error_delegate) {
// The target pref store should either have been initialized or should have an
// ongoing read.
CHECK(IsInitializationComplete() ||
// To catch case where target pref store initialization failed.
GetReadError() != PersistentPrefStore::PREF_READ_ERROR_NONE ||
// ReadPrefsAsync() was called but it's still ongoing.
target_pref_store_->HasReadErrorDelegate());
read_error_delegate_.emplace(error_delegate);
if (PersistentPrefStore::PrefReadError read_error = GetReadError();
read_error != PersistentPrefStore::PREF_READ_ERROR_NONE &&
error_delegate) {
error_delegate->OnError(read_error);
}
}
void WrapWithPrefixPrefStore::SchedulePendingLossyWrites() {
// This store is only a wrapper and relies on the target pref store being
// independently notified of this.
}
void WrapWithPrefixPrefStore::OnStoreDeletionFromDisk() {
// This store is only a wrapper and relies on the target pref store being
// independently notified of this.
}
void WrapWithPrefixPrefStore::ReportValueChanged(std::string_view key,
uint32_t flags) {
return target_pref_store_->ReportValueChanged(AddDottedPrefix(key), flags);
}
void WrapWithPrefixPrefStore::OnPrefValueChanged(std::string_view key) {
if (!HasDottedPrefix(key)) {
return;
}
std::string_view original_key(RemoveDottedPrefix(key));
for (PrefStore::Observer& observer : observers_) {
observer.OnPrefValueChanged(original_key);
}
}
void WrapWithPrefixPrefStore::OnInitializationCompleted(bool succeeded) {
if (PersistentPrefStore::PrefReadError read_error = GetReadError();
read_error != PersistentPrefStore::PREF_READ_ERROR_NONE &&
read_error_delegate_.has_value() && read_error_delegate_.value()) {
read_error_delegate_.value()->OnError(read_error);
}
for (PrefStore::Observer& observer : observers_) {
observer.OnInitializationCompleted(succeeded);
}
}
std::string WrapWithPrefixPrefStore::AddDottedPrefix(
std::string_view path) const {
return base::StrCat({dotted_prefix_, path});
}
std::string_view WrapWithPrefixPrefStore::RemoveDottedPrefix(
std::string_view path) const {
CHECK(HasDottedPrefix(path));
path.remove_prefix(dotted_prefix_.size());
return path;
}
bool WrapWithPrefixPrefStore::HasDottedPrefix(std::string_view path) const {
return base::StartsWith(path, dotted_prefix_);
}
bool WrapWithPrefixPrefStore::HasReadErrorDelegate() const {
return read_error_delegate_.has_value();
}