blob: 119666fa674e4d0db0b8c822c584f7a51aa385e6 [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_manager_impl.h"
#include <algorithm>
#include <utility>
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_value_store.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/preferences/persistent_pref_store_impl.h"
#include "services/preferences/pref_store_impl.h"
#include "services/preferences/scoped_pref_connection_builder.h"
#include "services/preferences/shared_pref_registry.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
namespace prefs {
class PrefStoreManagerImpl::ConnectorConnection
: public mojom::PrefStoreConnector {
public:
ConnectorConnection(PrefStoreManagerImpl* owner,
const service_manager::BindSourceInfo& source_info)
: owner_(owner), source_info_(source_info) {}
void Connect(
mojom::PrefRegistryPtr pref_registry,
ConnectCallback callback) override {
auto connection = owner_->shared_pref_registry_->CreateConnectionBuilder(
std::move(pref_registry), source_info_.identity, std::move(callback));
if (owner_->persistent_pref_store_ &&
owner_->persistent_pref_store_->initialized()) {
connection->ProvidePersistentPrefStore(
owner_->persistent_pref_store_.get());
} else {
owner_->pending_persistent_connections_.push_back(connection);
}
if (owner_->incognito_persistent_pref_store_underlay_) {
if (owner_->incognito_persistent_pref_store_underlay_->initialized()) {
connection->ProvideIncognitoPersistentPrefStoreUnderlay(
owner_->incognito_persistent_pref_store_underlay_.get(),
owner_->persistent_perf_names_);
} else {
owner_->pending_persistent_incognito_connections_.push_back(connection);
}
}
connection->ProvidePrefStoreConnections(owner_->read_only_pref_stores_);
}
private:
PrefStoreManagerImpl* const owner_;
const service_manager::BindSourceInfo source_info_;
};
PrefStoreManagerImpl::PrefStoreManagerImpl(
service_manager::mojom::ServiceRequest request,
PrefStore* managed_prefs,
PrefStore* supervised_user_prefs,
PrefStore* extension_prefs,
PrefStore* command_line_prefs,
PersistentPrefStore* user_prefs,
PersistentPrefStore* incognito_user_prefs_underlay,
PrefStore* recommended_prefs,
PrefRegistry* pref_registry,
std::vector<const char*> persistent_perf_names)
: service_binding_(this, std::move(request)),
shared_pref_registry_(std::make_unique<SharedPrefRegistry>(
base::WrapRefCounted(pref_registry))) {
// This store is done in-process so it's already "registered":
registry_.AddInterface<prefs::mojom::PrefStoreConnector>(
base::Bind(&PrefStoreManagerImpl::BindPrefStoreConnectorRequest,
base::Unretained(this)));
persistent_pref_store_ = std::make_unique<PersistentPrefStoreImpl>(
base::WrapRefCounted(user_prefs),
base::BindOnce(&PrefStoreManagerImpl::OnPersistentPrefStoreReady,
base::Unretained(this)));
if (incognito_user_prefs_underlay) {
incognito_persistent_pref_store_underlay_ =
std::make_unique<PersistentPrefStoreImpl>(
base::WrapRefCounted(incognito_user_prefs_underlay),
base::BindOnce(
&PrefStoreManagerImpl::OnIncognitoPersistentPrefStoreReady,
base::Unretained(this)));
persistent_perf_names_ = std::move(persistent_perf_names);
} else {
DCHECK(persistent_perf_names.empty());
}
RegisterPrefStore(PrefValueStore::MANAGED_STORE, managed_prefs);
RegisterPrefStore(PrefValueStore::SUPERVISED_USER_STORE,
supervised_user_prefs);
RegisterPrefStore(PrefValueStore::EXTENSION_STORE, extension_prefs);
RegisterPrefStore(PrefValueStore::COMMAND_LINE_STORE, command_line_prefs);
RegisterPrefStore(PrefValueStore::RECOMMENDED_STORE, recommended_prefs);
}
PrefStoreManagerImpl::~PrefStoreManagerImpl() = default;
base::OnceClosure PrefStoreManagerImpl::ShutDownClosure() {
return base::BindOnce(&PrefStoreManagerImpl::ShutDown,
weak_factory_.GetWeakPtr());
}
void PrefStoreManagerImpl::BindPrefStoreConnectorRequest(
prefs::mojom::PrefStoreConnectorRequest request,
const service_manager::BindSourceInfo& source_info) {
connector_bindings_.AddBinding(
std::make_unique<ConnectorConnection>(this, source_info),
std::move(request));
}
void PrefStoreManagerImpl::OnBindInterface(
const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
registry_.BindInterface(interface_name, std::move(interface_pipe),
source_info);
}
void PrefStoreManagerImpl::OnPersistentPrefStoreReady() {
DVLOG(1) << "PersistentPrefStore ready";
for (const auto& connection : pending_persistent_connections_)
connection->ProvidePersistentPrefStore(persistent_pref_store_.get());
pending_persistent_connections_.clear();
}
void PrefStoreManagerImpl::OnIncognitoPersistentPrefStoreReady() {
DVLOG(1) << "Incognito PersistentPrefStore ready";
for (const auto& connection : pending_persistent_connections_)
connection->ProvideIncognitoPersistentPrefStoreUnderlay(
incognito_persistent_pref_store_underlay_.get(),
persistent_perf_names_);
pending_persistent_incognito_connections_.clear();
}
void PrefStoreManagerImpl::RegisterPrefStore(PrefValueStore::PrefStoreType type,
PrefStore* pref_store) {
if (!pref_store)
return;
read_only_pref_stores_.emplace(
type, std::make_unique<PrefStoreImpl>(base::WrapRefCounted(pref_store)));
}
void PrefStoreManagerImpl::ShutDown() {
read_only_pref_stores_.clear();
persistent_pref_store_.reset();
Terminate();
}
} // namespace prefs