blob: 9c146da3caafec42841f9e7921378ff24f4cf4b8 [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.
#include "services/preferences/pref_store_impl.h"
#include <memory>
#include <set>
#include <utility>
#include "base/stl_util.h"
#include "base/values.h"
#include "services/preferences/public/cpp/lib/util.h"
namespace prefs {
class PrefStoreImpl::Observer {
public:
Observer(mojom::PrefStoreObserverPtr observer, std::set<std::string> prefs)
: observer_(std::move(observer)), prefs_(std::move(prefs)) {}
void OnInitializationCompleted(bool succeeded) {
observer_->OnInitializationCompleted(succeeded);
}
void OnPrefChanged(const std::string& key, const base::Value& value) const {
if (!base::ContainsKey(prefs_, key))
return;
std::vector<mojom::PrefUpdatePtr> updates;
updates.push_back(mojom::PrefUpdate::New(
key, mojom::PrefUpdateValue::NewAtomicUpdate(value.Clone()), 0));
observer_->OnPrefsChanged(std::move(updates));
}
void OnPrefRemoved(const std::string& key) const {
if (!base::ContainsKey(prefs_, key))
return;
std::vector<mojom::PrefUpdatePtr> updates;
updates.push_back(mojom::PrefUpdate::New(
key, mojom::PrefUpdateValue::NewAtomicUpdate(base::nullopt), 0));
observer_->OnPrefsChanged(std::move(updates));
}
private:
mojom::PrefStoreObserverPtr observer_;
const std::set<std::string> prefs_;
DISALLOW_COPY_AND_ASSIGN(Observer);
};
PrefStoreImpl::PrefStoreImpl(scoped_refptr<::PrefStore> pref_store)
: backing_pref_store_(std::move(pref_store)),
backing_pref_store_initialized_(false) {
DCHECK(backing_pref_store_);
if (backing_pref_store_->IsInitializationComplete())
OnInitializationCompleted(true);
backing_pref_store_->AddObserver(this);
}
PrefStoreImpl::~PrefStoreImpl() {
backing_pref_store_->RemoveObserver(this);
}
void PrefStoreImpl::OnPrefValueChanged(const std::string& key) {
auto dictionary = std::make_unique<base::DictionaryValue>();
const base::Value* value = nullptr;
if (backing_pref_store_->GetValue(key, &value)) {
for (const auto& observer : observers_)
observer->OnPrefChanged(key, *value);
} else {
for (const auto& observer : observers_)
observer->OnPrefRemoved(key);
}
}
void PrefStoreImpl::OnInitializationCompleted(bool succeeded) {
// Some pref stores call this more than once. We just ignore all calls after
// the first.
if (backing_pref_store_initialized_)
DCHECK(succeeded);
backing_pref_store_initialized_ = succeeded;
for (const auto& observer : observers_)
observer->OnInitializationCompleted(succeeded);
}
mojom::PrefStoreConnectionPtr PrefStoreImpl::AddObserver(
const std::vector<std::string>& prefs_to_observe) {
mojom::PrefStoreObserverPtr observer_ptr;
auto request = mojo::MakeRequest(&observer_ptr);
std::set<std::string> observed_prefs(prefs_to_observe.begin(),
prefs_to_observe.end());
auto result = mojom::PrefStoreConnection::New(
std::move(request),
base::Value::FromUniquePtrValue(
FilterPrefs(backing_pref_store_->GetValues(), observed_prefs)),
backing_pref_store_->IsInitializationComplete());
observers_.push_back(std::make_unique<Observer>(std::move(observer_ptr),
std::move(observed_prefs)));
return result;
}
} // namespace prefs