| Index: services/preferences/public/cpp/pref_service_factory.cc
|
| diff --git a/services/preferences/public/cpp/pref_service_factory.cc b/services/preferences/public/cpp/pref_service_factory.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..27067c6e8516175b6f82b5e30541981d9b6001dd
|
| --- /dev/null
|
| +++ b/services/preferences/public/cpp/pref_service_factory.cc
|
| @@ -0,0 +1,158 @@
|
| +// 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/public/cpp/pref_service_factory.h"
|
| +
|
| +#include "base/callback_helpers.h"
|
| +#include "components/prefs/persistent_pref_store.h"
|
| +#include "components/prefs/pref_notifier_impl.h"
|
| +#include "components/prefs/pref_registry.h"
|
| +#include "components/prefs/pref_service.h"
|
| +#include "components/prefs/pref_value_store.h"
|
| +#include "services/preferences/public/cpp/persistent_pref_store_client.h"
|
| +#include "services/preferences/public/cpp/pref_store_client.h"
|
| +#include "services/preferences/public/interfaces/preferences.mojom.h"
|
| +#include "services/service_manager/public/cpp/connector.h"
|
| +
|
| +namespace prefs {
|
| +namespace {
|
| +
|
| +// Used to implement a "fire and forget" pattern where we call an interface
|
| +// method, with an attached error handler, but don't care to hold on to the
|
| +// InterfacePtr after.
|
| +template <typename Interface>
|
| +class RefCountedInterfacePtr
|
| + : public base::RefCounted<RefCountedInterfacePtr<Interface>> {
|
| + public:
|
| + mojo::InterfacePtr<Interface>& get() { return ptr_; }
|
| + void reset() { ptr_.reset(); }
|
| +
|
| + private:
|
| + friend class base::RefCounted<RefCountedInterfacePtr<Interface>>;
|
| + ~RefCountedInterfacePtr() = default;
|
| +
|
| + mojo::InterfacePtr<Interface> ptr_;
|
| +};
|
| +
|
| +void DoNothingHandleReadError(PersistentPrefStore::PrefReadError error) {}
|
| +
|
| +class ConnectionBarrier : public base::RefCounted<ConnectionBarrier> {
|
| + public:
|
| + static void Create(service_manager::Connector* connector,
|
| + scoped_refptr<PrefRegistry> pref_registry,
|
| + ConnectCallback callback);
|
| +
|
| + private:
|
| + friend class base::RefCounted<ConnectionBarrier>;
|
| + ConnectionBarrier(scoped_refptr<PrefRegistry> pref_registry,
|
| + scoped_refptr<PersistentPrefStore> persistent_pref_store,
|
| + ConnectCallback callback);
|
| + ~ConnectionBarrier() = default;
|
| +
|
| + void OnConnect(
|
| + scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>> unused,
|
| + scoped_refptr<PrefRegistry> pref_registry,
|
| + std::unordered_map<PrefValueStore::PrefStoreType,
|
| + mojom::PrefStoreConnectionPtr> connections);
|
| +
|
| + void OnConnectError(
|
| + scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>> unused);
|
| +
|
| + scoped_refptr<PrefRegistry> pref_registry_;
|
| + scoped_refptr<PersistentPrefStore> persistent_pref_store_;
|
| + ConnectCallback callback_;
|
| +};
|
| +
|
| +scoped_refptr<PrefStore> CreatePrefStore(
|
| + PrefValueStore::PrefStoreType store_type,
|
| + std::unordered_map<PrefValueStore::PrefStoreType,
|
| + mojom::PrefStoreConnectionPtr>* connections) {
|
| + auto pref_store_it = connections->find(store_type);
|
| + if (pref_store_it != connections->end()) {
|
| + return make_scoped_refptr(
|
| + new PrefStoreClient(std::move(pref_store_it->second)));
|
| + } else {
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| +ConnectionBarrier::ConnectionBarrier(
|
| + scoped_refptr<PrefRegistry> pref_registry,
|
| + scoped_refptr<PersistentPrefStore> persistent_pref_store,
|
| + ConnectCallback callback)
|
| + : pref_registry_(std::move(pref_registry)),
|
| + persistent_pref_store_(std::move(persistent_pref_store)),
|
| + callback_(std::move(callback)) {}
|
| +
|
| +void ConnectionBarrier::OnConnect(
|
| + scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>>
|
| + connector_ptr,
|
| + scoped_refptr<PrefRegistry> pref_registry,
|
| + std::unordered_map<PrefValueStore::PrefStoreType,
|
| + mojom::PrefStoreConnectionPtr> connections) {
|
| + scoped_refptr<PrefStore> managed_prefs =
|
| + CreatePrefStore(PrefValueStore::MANAGED_STORE, &connections);
|
| + scoped_refptr<PrefStore> supervised_user_prefs =
|
| + CreatePrefStore(PrefValueStore::SUPERVISED_USER_STORE, &connections);
|
| + scoped_refptr<PrefStore> extension_prefs =
|
| + CreatePrefStore(PrefValueStore::EXTENSION_STORE, &connections);
|
| + scoped_refptr<PrefStore> command_line_prefs =
|
| + CreatePrefStore(PrefValueStore::COMMAND_LINE_STORE, &connections);
|
| + scoped_refptr<PrefStore> recommended_prefs =
|
| + CreatePrefStore(PrefValueStore::RECOMMENDED_STORE, &connections);
|
| + scoped_refptr<PrefStore> default_prefs =
|
| + CreatePrefStore(PrefValueStore::DEFAULT_STORE, &connections);
|
| + PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
|
| + auto* pref_value_store = new PrefValueStore(
|
| + managed_prefs.get(), supervised_user_prefs.get(), extension_prefs.get(),
|
| + command_line_prefs.get(), persistent_pref_store_.get(),
|
| + recommended_prefs.get(), default_prefs.get(), pref_notifier);
|
| + base::ResetAndReturn(&callback_)
|
| + .Run(base::MakeUnique<::PrefService>(
|
| + pref_notifier, pref_value_store, persistent_pref_store_.get(),
|
| + pref_registry_.get(), base::Bind(&DoNothingHandleReadError), true));
|
| + connector_ptr->reset();
|
| +}
|
| +
|
| +void ConnectionBarrier::OnConnectError(
|
| + scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>>
|
| + connector_ptr) {
|
| + callback_.Run(nullptr);
|
| + connector_ptr->reset();
|
| +}
|
| +
|
| +// static
|
| +void ConnectionBarrier::Create(service_manager::Connector* connector,
|
| + scoped_refptr<PrefRegistry> pref_registry,
|
| + ConnectCallback callback) {
|
| + // Connect to user pref store.
|
| + mojom::PersistentPrefStoreConnectorPtr persistent_connector_ptr;
|
| + connector->BindInterface(mojom::kPrefStoreServiceName,
|
| + &persistent_connector_ptr);
|
| + auto barrier = make_scoped_refptr(new ConnectionBarrier(
|
| + std::move(pref_registry),
|
| + make_scoped_refptr(
|
| + new PersistentPrefStoreClient(std::move(persistent_connector_ptr))),
|
| + std::move(callback)));
|
| +
|
| + // Connect to all other pref stores.
|
| + auto connector_ptr = make_scoped_refptr(
|
| + new RefCountedInterfacePtr<mojom::PrefStoreConnector>());
|
| + connector->BindInterface(mojom::kPrefStoreServiceName, &connector_ptr->get());
|
| + connector_ptr->get().set_connection_error_handler(
|
| + base::Bind(&ConnectionBarrier::OnConnectError, barrier, connector_ptr));
|
| + connector_ptr->get()->Connect(base::Bind(&ConnectionBarrier::OnConnect,
|
| + barrier, connector_ptr,
|
| + std::move(pref_registry)));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +void ConnectToPrefService(service_manager::Connector* connector,
|
| + scoped_refptr<PrefRegistry> pref_registry,
|
| + const ConnectCallback& callback) {
|
| + ConnectionBarrier::Create(connector, std::move(pref_registry), callback);
|
| +}
|
| +
|
| +} // namespace prefs
|
|
|