[prefs] Add PersistentPrefStore::HasReadErrorDelegate()
This method can be used as proxy to detect if ReadPrefsAsync() has been called on a pref store. Bug: 336776819 Change-Id: I21ba0a5f4d5a00d1710303359989277e4a940410 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5535432 Reviewed-by: Gabriel Charette <gab@chromium.org> Commit-Queue: Ankush Singh <ankushkush@google.com> Cr-Commit-Position: refs/heads/main@{#1301154}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
19fda2d589
commit
a77ee83987
components
prefs
in_memory_pref_store.ccin_memory_pref_store.hjson_pref_store.ccjson_pref_store.hjson_pref_store_unittest.ccoverlay_user_pref_store.ccoverlay_user_pref_store.hoverlay_user_pref_store_unittest.ccpersistent_pref_store.hsegregated_pref_store.ccsegregated_pref_store.hsegregated_pref_store_unittest.cctesting_pref_store.cctesting_pref_store.h
sync_preferences
@@ -90,3 +90,7 @@ void InMemoryPrefStore::ReportValueChanged(const std::string& key,
|
|||||||
bool InMemoryPrefStore::IsInMemoryPrefStore() const {
|
bool InMemoryPrefStore::IsInMemoryPrefStore() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InMemoryPrefStore::HasReadErrorDelegate() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@@ -54,6 +54,7 @@ class COMPONENTS_PREFS_EXPORT InMemoryPrefStore : public PersistentPrefStore {
|
|||||||
void OnStoreDeletionFromDisk() override {}
|
void OnStoreDeletionFromDisk() override {}
|
||||||
bool IsInMemoryPrefStore() const override;
|
bool IsInMemoryPrefStore() const override;
|
||||||
void RemoveValuesByPrefixSilently(const std::string& prefix) override;
|
void RemoveValuesByPrefixSilently(const std::string& prefix) override;
|
||||||
|
bool HasReadErrorDelegate() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~InMemoryPrefStore() override;
|
~InMemoryPrefStore() override;
|
||||||
|
@@ -296,7 +296,7 @@ void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
|
|||||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
|
|
||||||
initialized_ = false;
|
initialized_ = false;
|
||||||
error_delegate_.reset(error_delegate);
|
error_delegate_.emplace(error_delegate);
|
||||||
|
|
||||||
// Weakly binds the read task so that it doesn't kick in during shutdown.
|
// Weakly binds the read task so that it doesn't kick in during shutdown.
|
||||||
file_task_runner_->PostTaskAndReplyWithResult(
|
file_task_runner_->PostTaskAndReplyWithResult(
|
||||||
@@ -527,8 +527,10 @@ void JsonPrefStore::FinalizeFileRead(bool initialization_successful,
|
|||||||
if (schedule_write)
|
if (schedule_write)
|
||||||
ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS);
|
ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS);
|
||||||
|
|
||||||
if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
|
if (error_delegate_.has_value() && error_delegate_.value() &&
|
||||||
error_delegate_->OnError(read_error_);
|
read_error_ != PREF_READ_ERROR_NONE) {
|
||||||
|
error_delegate_.value()->OnError(read_error_);
|
||||||
|
}
|
||||||
|
|
||||||
for (PrefStore::Observer& observer : observers_)
|
for (PrefStore::Observer& observer : observers_)
|
||||||
observer.OnInitializationCompleted(true);
|
observer.OnInitializationCompleted(true);
|
||||||
@@ -546,3 +548,7 @@ void JsonPrefStore::ScheduleWrite(uint32_t flags) {
|
|||||||
writer_.ScheduleWriteWithBackgroundDataSerializer(this);
|
writer_.ScheduleWriteWithBackgroundDataSerializer(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JsonPrefStore::HasReadErrorDelegate() const {
|
||||||
|
return error_delegate_.has_value();
|
||||||
|
}
|
||||||
|
@@ -95,6 +95,7 @@ class COMPONENTS_PREFS_EXPORT JsonPrefStore final
|
|||||||
void RemoveValue(const std::string& key, uint32_t flags) override;
|
void RemoveValue(const std::string& key, uint32_t flags) override;
|
||||||
bool ReadOnly() const override;
|
bool ReadOnly() const override;
|
||||||
PrefReadError GetReadError() const override;
|
PrefReadError GetReadError() const override;
|
||||||
|
bool HasReadErrorDelegate() const override;
|
||||||
// Note this method may be asynchronous if this instance has a |pref_filter_|
|
// Note this method may be asynchronous if this instance has a |pref_filter_|
|
||||||
// in which case it will return PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE.
|
// in which case it will return PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE.
|
||||||
// See details in pref_filter.h.
|
// See details in pref_filter.h.
|
||||||
@@ -114,6 +115,7 @@ class COMPONENTS_PREFS_EXPORT JsonPrefStore final
|
|||||||
// Just like RemoveValue(), but removes all the prefs that start with
|
// Just like RemoveValue(), but removes all the prefs that start with
|
||||||
// |prefix|. Used for pref-initialization cleanup.
|
// |prefix|. Used for pref-initialization cleanup.
|
||||||
void RemoveValuesByPrefixSilently(const std::string& prefix) override;
|
void RemoveValuesByPrefixSilently(const std::string& prefix) override;
|
||||||
|
|
||||||
// Registers |on_next_successful_write_reply| to be called once, on the next
|
// Registers |on_next_successful_write_reply| to be called once, on the next
|
||||||
// successful write event of |writer_|.
|
// successful write event of |writer_|.
|
||||||
// |on_next_successful_write_reply| will be called on the thread from which
|
// |on_next_successful_write_reply| will be called on the thread from which
|
||||||
@@ -202,7 +204,8 @@ class COMPONENTS_PREFS_EXPORT JsonPrefStore final
|
|||||||
std::unique_ptr<PrefFilter> pref_filter_;
|
std::unique_ptr<PrefFilter> pref_filter_;
|
||||||
base::ObserverList<PrefStore::Observer, true>::Unchecked observers_;
|
base::ObserverList<PrefStore::Observer, true>::Unchecked observers_;
|
||||||
|
|
||||||
std::unique_ptr<ReadErrorDelegate> error_delegate_;
|
// Optional so we can differentiate `nullopt` from `nullptr`.
|
||||||
|
std::optional<std::unique_ptr<ReadErrorDelegate>> error_delegate_;
|
||||||
|
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
bool filtering_in_progress_;
|
bool filtering_in_progress_;
|
||||||
|
@@ -558,6 +558,29 @@ TEST_P(JsonPrefStoreTest, RemoveValuesByPrefix) {
|
|||||||
EXPECT_TRUE(pref_store->GetValue(other_name, &value));
|
EXPECT_TRUE(pref_store->GetValue(other_name, &value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(JsonPrefStoreTest, HasReadErrorDelegate) {
|
||||||
|
base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
|
||||||
|
ASSERT_FALSE(PathExists(bogus_input_file));
|
||||||
|
auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);
|
||||||
|
|
||||||
|
EXPECT_FALSE(pref_store->HasReadErrorDelegate());
|
||||||
|
|
||||||
|
pref_store->ReadPrefsAsync(new MockReadErrorDelegate);
|
||||||
|
EXPECT_TRUE(pref_store->HasReadErrorDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(JsonPrefStoreTest, HasReadErrorDelegateWithNullDelegate) {
|
||||||
|
base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
|
||||||
|
ASSERT_FALSE(PathExists(bogus_input_file));
|
||||||
|
auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);
|
||||||
|
|
||||||
|
EXPECT_FALSE(pref_store->HasReadErrorDelegate());
|
||||||
|
|
||||||
|
pref_store->ReadPrefsAsync(nullptr);
|
||||||
|
// Returns true even though no instance was passed.
|
||||||
|
EXPECT_TRUE(pref_store->HasReadErrorDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
JsonPrefStoreTestVariations,
|
JsonPrefStoreTestVariations,
|
||||||
JsonPrefStoreTest,
|
JsonPrefStoreTest,
|
||||||
|
@@ -244,3 +244,7 @@ bool OverlayUserPrefStore::ShallBeStoredInPersistent(
|
|||||||
std::string_view key) const {
|
std::string_view key) const {
|
||||||
return persistent_names_set_.find(key) != persistent_names_set_.end();
|
return persistent_names_set_.find(key) != persistent_names_set_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OverlayUserPrefStore::HasReadErrorDelegate() const {
|
||||||
|
return persistent_user_pref_store_->HasReadErrorDelegate();
|
||||||
|
}
|
||||||
|
@@ -73,6 +73,7 @@ class COMPONENTS_PREFS_EXPORT OverlayUserPrefStore
|
|||||||
void RegisterPersistentPref(const std::string& key);
|
void RegisterPersistentPref(const std::string& key);
|
||||||
|
|
||||||
void OnStoreDeletionFromDisk() override;
|
void OnStoreDeletionFromDisk() override;
|
||||||
|
bool HasReadErrorDelegate() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~OverlayUserPrefStore() override;
|
~OverlayUserPrefStore() override;
|
||||||
|
@@ -243,4 +243,13 @@ TEST_F(OverlayUserPrefStoreTest, CommitPendingWriteWithCallback) {
|
|||||||
TestCommitPendingWriteWithCallback(overlay_.get(), &task_environment_);
|
TestCommitPendingWriteWithCallback(overlay_.get(), &task_environment_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(OverlayUserPrefStoreTest, HasReadErrorDelegate) {
|
||||||
|
ASSERT_FALSE(underlay_->HasReadErrorDelegate());
|
||||||
|
EXPECT_FALSE(overlay_->HasReadErrorDelegate());
|
||||||
|
|
||||||
|
underlay_->ReadPrefsAsync(nullptr);
|
||||||
|
ASSERT_TRUE(underlay_->HasReadErrorDelegate());
|
||||||
|
EXPECT_TRUE(overlay_->HasReadErrorDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@@ -83,8 +83,14 @@ class COMPONENTS_PREFS_EXPORT PersistentPrefStore : public WriteablePrefStore {
|
|||||||
// TODO(crbug.com/41447167) Remove this after fixing the bug.
|
// TODO(crbug.com/41447167) Remove this after fixing the bug.
|
||||||
virtual bool IsInMemoryPrefStore() const;
|
virtual bool IsInMemoryPrefStore() const;
|
||||||
|
|
||||||
|
// Returns whether this holds a read error delegate (can be null), passed
|
||||||
|
// during ReadPrefsAsync().
|
||||||
|
// When used in conjugation with IsInitializationComplete() and
|
||||||
|
// GetReadError(), this can be used to identity if there's a pending read.
|
||||||
|
virtual bool HasReadErrorDelegate() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~PersistentPrefStore() override {}
|
~PersistentPrefStore() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COMPONENTS_PREFS_PERSISTENT_PREF_STORE_H_
|
#endif // COMPONENTS_PREFS_PERSISTENT_PREF_STORE_H_
|
||||||
|
@@ -42,10 +42,11 @@ void SegregatedPrefStore::UnderlyingPrefStoreObserver::
|
|||||||
if (!outer_->IsInitializationComplete())
|
if (!outer_->IsInitializationComplete())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (outer_->read_error_delegate_) {
|
if (outer_->read_error_delegate_.has_value() &&
|
||||||
|
outer_->read_error_delegate_.value()) {
|
||||||
PersistentPrefStore::PrefReadError read_error = outer_->GetReadError();
|
PersistentPrefStore::PrefReadError read_error = outer_->GetReadError();
|
||||||
if (read_error != PersistentPrefStore::PREF_READ_ERROR_NONE)
|
if (read_error != PersistentPrefStore::PREF_READ_ERROR_NONE)
|
||||||
outer_->read_error_delegate_->OnError(read_error);
|
outer_->read_error_delegate_.value()->OnError(read_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& observer : outer_->observers_)
|
for (auto& observer : outer_->observers_)
|
||||||
@@ -171,9 +172,9 @@ PersistentPrefStore::PrefReadError SegregatedPrefStore::ReadPrefs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SegregatedPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
|
void SegregatedPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
|
||||||
read_error_delegate_.reset(error_delegate);
|
read_error_delegate_.emplace(error_delegate);
|
||||||
default_pref_store_->ReadPrefsAsync(NULL);
|
default_pref_store_->ReadPrefsAsync(nullptr);
|
||||||
selected_pref_store_->ReadPrefsAsync(NULL);
|
selected_pref_store_->ReadPrefsAsync(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SegregatedPrefStore::CommitPendingWrite(
|
void SegregatedPrefStore::CommitPendingWrite(
|
||||||
@@ -226,3 +227,7 @@ const PersistentPrefStore* SegregatedPrefStore::StoreForKey(
|
|||||||
: default_pref_store_)
|
: default_pref_store_)
|
||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SegregatedPrefStore::HasReadErrorDelegate() const {
|
||||||
|
return read_error_delegate_.has_value();
|
||||||
|
}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@@ -81,6 +82,7 @@ class COMPONENTS_PREFS_EXPORT SegregatedPrefStore : public PersistentPrefStore {
|
|||||||
base::OnceClosure()) override;
|
base::OnceClosure()) override;
|
||||||
void SchedulePendingLossyWrites() override;
|
void SchedulePendingLossyWrites() override;
|
||||||
void OnStoreDeletionFromDisk() override;
|
void OnStoreDeletionFromDisk() override;
|
||||||
|
bool HasReadErrorDelegate() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~SegregatedPrefStore() override;
|
~SegregatedPrefStore() override;
|
||||||
@@ -121,7 +123,9 @@ class COMPONENTS_PREFS_EXPORT SegregatedPrefStore : public PersistentPrefStore {
|
|||||||
const scoped_refptr<PersistentPrefStore> selected_pref_store_;
|
const scoped_refptr<PersistentPrefStore> selected_pref_store_;
|
||||||
const PrefNameSet selected_preference_names_;
|
const PrefNameSet selected_preference_names_;
|
||||||
|
|
||||||
std::unique_ptr<PersistentPrefStore::ReadErrorDelegate> read_error_delegate_;
|
// Optional so we can differentiate `nullopt` from `nullptr`.
|
||||||
|
std::optional<std::unique_ptr<PersistentPrefStore::ReadErrorDelegate>>
|
||||||
|
read_error_delegate_;
|
||||||
base::ObserverList<PrefStore::Observer, true>::Unchecked observers_;
|
base::ObserverList<PrefStore::Observer, true>::Unchecked observers_;
|
||||||
UnderlyingPrefStoreObserver default_observer_;
|
UnderlyingPrefStoreObserver default_observer_;
|
||||||
UnderlyingPrefStoreObserver selected_observer_;
|
UnderlyingPrefStoreObserver selected_observer_;
|
||||||
|
@@ -383,6 +383,21 @@ TEST_F(SegregatedPrefStoreTest, GetValues) {
|
|||||||
EXPECT_EQ(base::Value(kValue1), *value);
|
EXPECT_EQ(base::Value(kValue1), *value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SegregatedPrefStoreTest, HasReadErrorDelegate) {
|
||||||
|
EXPECT_FALSE(segregated_store_->HasReadErrorDelegate());
|
||||||
|
|
||||||
|
segregated_store_->ReadPrefsAsync(GetReadErrorDelegate().release());
|
||||||
|
EXPECT_TRUE(segregated_store_->HasReadErrorDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SegregatedPrefStoreTest, HasReadErrorDelegateWithNullDelegate) {
|
||||||
|
EXPECT_FALSE(segregated_store_->HasReadErrorDelegate());
|
||||||
|
|
||||||
|
segregated_store_->ReadPrefsAsync(nullptr);
|
||||||
|
// Returns true even though no instance was passed.
|
||||||
|
EXPECT_TRUE(segregated_store_->HasReadErrorDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
WithoutCallback,
|
WithoutCallback,
|
||||||
SegregatedPrefStoreTest,
|
SegregatedPrefStoreTest,
|
||||||
|
@@ -147,7 +147,7 @@ PersistentPrefStore::PrefReadError TestingPrefStore::ReadPrefs() {
|
|||||||
|
|
||||||
void TestingPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
|
void TestingPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
|
||||||
DCHECK(!pending_async_read_);
|
DCHECK(!pending_async_read_);
|
||||||
error_delegate_.reset(error_delegate);
|
error_delegate_.emplace(error_delegate);
|
||||||
if (block_async_read_)
|
if (block_async_read_)
|
||||||
pending_async_read_ = true;
|
pending_async_read_ = true;
|
||||||
else
|
else
|
||||||
@@ -176,8 +176,10 @@ void TestingPrefStore::NotifyPrefValueChanged(const std::string& key) {
|
|||||||
void TestingPrefStore::NotifyInitializationCompleted() {
|
void TestingPrefStore::NotifyInitializationCompleted() {
|
||||||
DCHECK(!init_complete_);
|
DCHECK(!init_complete_);
|
||||||
init_complete_ = true;
|
init_complete_ = true;
|
||||||
if (read_success_ && read_error_ != PREF_READ_ERROR_NONE && error_delegate_)
|
if (read_success_ && read_error_ != PREF_READ_ERROR_NONE &&
|
||||||
error_delegate_->OnError(read_error_);
|
error_delegate_.has_value() && error_delegate_.value()) {
|
||||||
|
error_delegate_.value()->OnError(read_error_);
|
||||||
|
}
|
||||||
for (Observer& observer : observers_)
|
for (Observer& observer : observers_)
|
||||||
observer.OnInitializationCompleted(read_success_);
|
observer.OnInitializationCompleted(read_success_);
|
||||||
}
|
}
|
||||||
@@ -294,3 +296,7 @@ void TestingPrefStore::CheckPrefIsSerializable(const std::string& key,
|
|||||||
EXPECT_TRUE(base::JSONWriter::Write(value, &json))
|
EXPECT_TRUE(base::JSONWriter::Write(value, &json))
|
||||||
<< "Pref \"" << key << "\" is not serializable as JSON.";
|
<< "Pref \"" << key << "\" is not serializable as JSON.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TestingPrefStore::HasReadErrorDelegate() const {
|
||||||
|
return error_delegate_.has_value();
|
||||||
|
}
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ class TestingPrefStore : public PersistentPrefStore {
|
|||||||
void CommitPendingWrite(base::OnceClosure reply_callback,
|
void CommitPendingWrite(base::OnceClosure reply_callback,
|
||||||
base::OnceClosure synchronous_done_callback) override;
|
base::OnceClosure synchronous_done_callback) override;
|
||||||
void SchedulePendingLossyWrites() override;
|
void SchedulePendingLossyWrites() override;
|
||||||
|
bool HasReadErrorDelegate() const override;
|
||||||
|
|
||||||
// Marks the store as having completed initialization.
|
// Marks the store as having completed initialization.
|
||||||
void SetInitializationCompleted();
|
void SetInitializationCompleted();
|
||||||
@@ -127,7 +129,8 @@ class TestingPrefStore : public PersistentPrefStore {
|
|||||||
// mutation.
|
// mutation.
|
||||||
bool committed_;
|
bool committed_;
|
||||||
|
|
||||||
std::unique_ptr<ReadErrorDelegate> error_delegate_;
|
// Optional so we can differentiate `nullopt` from `nullptr`.
|
||||||
|
std::optional<std::unique_ptr<ReadErrorDelegate>> error_delegate_;
|
||||||
base::ObserverList<PrefStore::Observer, true>::Unchecked observers_;
|
base::ObserverList<PrefStore::Observer, true>::Unchecked observers_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -68,10 +68,11 @@ void DualLayerUserPrefStore::UnderlyingPrefStoreObserver::
|
|||||||
|
|
||||||
// Forward error if any of the underlying store reported error upon
|
// Forward error if any of the underlying store reported error upon
|
||||||
// ReadPrefsAsync().
|
// ReadPrefsAsync().
|
||||||
if (outer_->read_error_delegate_) {
|
if (outer_->read_error_delegate_.has_value() &&
|
||||||
|
outer_->read_error_delegate_.value()) {
|
||||||
if (auto read_error = outer_->GetReadError();
|
if (auto read_error = outer_->GetReadError();
|
||||||
read_error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
|
read_error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
|
||||||
outer_->read_error_delegate_->OnError(read_error);
|
outer_->read_error_delegate_.value()->OnError(read_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +378,7 @@ void DualLayerUserPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
|
|||||||
// The store is expected to take ownership of `error_delegate`, thus it's not
|
// The store is expected to take ownership of `error_delegate`, thus it's not
|
||||||
// valid to forward the same to the two underlying stores. Instead, if any
|
// valid to forward the same to the two underlying stores. Instead, if any
|
||||||
// error occurs, it's reported in OnInitializationCompleted() handle.
|
// error occurs, it's reported in OnInitializationCompleted() handle.
|
||||||
read_error_delegate_.reset(error_delegate);
|
read_error_delegate_.emplace(error_delegate);
|
||||||
local_pref_store_->ReadPrefsAsync(nullptr);
|
local_pref_store_->ReadPrefsAsync(nullptr);
|
||||||
account_pref_store_->ReadPrefsAsync(nullptr);
|
account_pref_store_->ReadPrefsAsync(nullptr);
|
||||||
}
|
}
|
||||||
@@ -798,4 +799,8 @@ void DualLayerUserPrefStore::SetValueInAccountStoreOnly(const std::string& key,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DualLayerUserPrefStore::HasReadErrorDelegate() const {
|
||||||
|
return read_error_delegate_.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sync_preferences
|
} // namespace sync_preferences
|
||||||
|
@@ -105,6 +105,7 @@ class DualLayerUserPrefStore : public PersistentPrefStore,
|
|||||||
base::OnceClosure()) override;
|
base::OnceClosure()) override;
|
||||||
void SchedulePendingLossyWrites() override;
|
void SchedulePendingLossyWrites() override;
|
||||||
void OnStoreDeletionFromDisk() override;
|
void OnStoreDeletionFromDisk() override;
|
||||||
|
bool HasReadErrorDelegate() const override;
|
||||||
|
|
||||||
// SyncServiceObserver implementation
|
// SyncServiceObserver implementation
|
||||||
void OnStateChanged(syncer::SyncService* sync_service) override;
|
void OnStateChanged(syncer::SyncService* sync_service) override;
|
||||||
@@ -205,7 +206,9 @@ class DualLayerUserPrefStore : public PersistentPrefStore,
|
|||||||
UnderlyingPrefStoreObserver local_pref_store_observer_;
|
UnderlyingPrefStoreObserver local_pref_store_observer_;
|
||||||
UnderlyingPrefStoreObserver account_pref_store_observer_;
|
UnderlyingPrefStoreObserver account_pref_store_observer_;
|
||||||
|
|
||||||
std::unique_ptr<PersistentPrefStore::ReadErrorDelegate> read_error_delegate_;
|
// Optional so we can differentiate `nullopt` from `nullptr`.
|
||||||
|
std::optional<std::unique_ptr<PersistentPrefStore::ReadErrorDelegate>>
|
||||||
|
read_error_delegate_;
|
||||||
|
|
||||||
// List of preference types currently syncing.
|
// List of preference types currently syncing.
|
||||||
base::flat_set<syncer::ModelType> active_types_;
|
base::flat_set<syncer::ModelType> active_types_;
|
||||||
|
@@ -323,6 +323,22 @@ TEST_F(DualLayerUserPrefStoreInitializationTest,
|
|||||||
EXPECT_TRUE(store()->IsInitializationComplete());
|
EXPECT_TRUE(store()->IsInitializationComplete());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DualLayerUserPrefStoreInitializationTest, HasReadErrorDelegate) {
|
||||||
|
EXPECT_FALSE(store()->HasReadErrorDelegate());
|
||||||
|
|
||||||
|
store()->ReadPrefsAsync(new MockReadErrorDelegate);
|
||||||
|
EXPECT_TRUE(store()->HasReadErrorDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DualLayerUserPrefStoreInitializationTest,
|
||||||
|
HasReadErrorDelegateWithNullDelegate) {
|
||||||
|
EXPECT_FALSE(store()->HasReadErrorDelegate());
|
||||||
|
|
||||||
|
store()->ReadPrefsAsync(nullptr);
|
||||||
|
// Returns true even though no instance was passed.
|
||||||
|
EXPECT_TRUE(store()->HasReadErrorDelegate());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(DualLayerUserPrefStoreInitializationTest,
|
TEST_F(DualLayerUserPrefStoreInitializationTest,
|
||||||
ShouldReportInitializationCompleteAsyncReadAsync) {
|
ShouldReportInitializationCompleteAsyncReadAsync) {
|
||||||
// Should report init completion after async read for underlying stores is
|
// Should report init completion after async read for underlying stores is
|
||||||
|
Reference in New Issue
Block a user