OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "services/preferences/public/cpp/pref_service_factory.h" | |
6 | |
7 #include "base/callback_helpers.h" | |
8 #include "components/prefs/persistent_pref_store.h" | |
9 #include "components/prefs/pref_notifier_impl.h" | |
10 #include "components/prefs/pref_registry.h" | |
11 #include "components/prefs/pref_service.h" | |
12 #include "components/prefs/pref_value_store.h" | |
13 #include "services/preferences/public/cpp/persistent_pref_store_client.h" | |
14 #include "services/preferences/public/cpp/pref_store_client.h" | |
15 #include "services/preferences/public/interfaces/preferences.mojom.h" | |
16 #include "services/service_manager/public/cpp/connector.h" | |
17 | |
18 namespace prefs { | |
19 namespace { | |
20 | |
21 // Used to implement a "fire and forget" pattern where we call an interface | |
22 // method, with an attached error handler, but don't care to hold on to the | |
23 // InterfacePtr after. | |
24 template <typename Interface> | |
25 class RefCountedInterfacePtr | |
26 : public base::RefCounted<RefCountedInterfacePtr<Interface>> { | |
27 public: | |
28 mojo::InterfacePtr<Interface>& get() { return ptr_; } | |
29 void reset() { ptr_.reset(); } | |
30 | |
31 private: | |
32 friend class base::RefCounted<RefCountedInterfacePtr<Interface>>; | |
33 ~RefCountedInterfacePtr() = default; | |
34 | |
35 mojo::InterfacePtr<Interface> ptr_; | |
36 }; | |
37 | |
38 void DoNothingHandleReadError(PersistentPrefStore::PrefReadError error) {} | |
39 | |
40 class ConnectionBarrier : public base::RefCounted<ConnectionBarrier> { | |
41 public: | |
42 static void Create(service_manager::Connector* connector, | |
43 scoped_refptr<PrefRegistry> pref_registry, | |
44 ConnectCallback callback); | |
45 | |
46 private: | |
47 friend class base::RefCounted<ConnectionBarrier>; | |
48 ConnectionBarrier(scoped_refptr<PrefRegistry> pref_registry, | |
49 scoped_refptr<PersistentPrefStore> persistent_pref_store, | |
50 ConnectCallback callback); | |
51 ~ConnectionBarrier() = default; | |
52 | |
53 scoped_refptr<PrefStore> CreatePrefStore( | |
54 PrefValueStore::PrefStoreType store_type, | |
55 std::unordered_map<PrefValueStore::PrefStoreType, | |
56 mojom::PrefStoreConnectionPtr>* connections); | |
57 | |
58 void OnConnect( | |
59 scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>> unused, | |
60 scoped_refptr<PrefRegistry> pref_registry, | |
61 std::unordered_map<PrefValueStore::PrefStoreType, | |
62 mojom::PrefStoreConnectionPtr> connections); | |
63 | |
64 void OnConnectError( | |
65 scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>> unused); | |
66 | |
67 scoped_refptr<PrefRegistry> pref_registry_; | |
68 scoped_refptr<PersistentPrefStore> persistent_pref_store_; | |
69 ConnectCallback callback_; | |
70 }; | |
71 | |
72 scoped_refptr<PrefStore> ConnectionBarrier::CreatePrefStore( | |
Sam McNally
2017/03/22 05:43:04
Can this be static or (better yet) a non-member fu
| |
73 PrefValueStore::PrefStoreType store_type, | |
74 std::unordered_map<PrefValueStore::PrefStoreType, | |
75 mojom::PrefStoreConnectionPtr>* connections) { | |
76 auto pref_store_it = connections->find(store_type); | |
77 if (pref_store_it != connections->end()) { | |
78 return make_scoped_refptr( | |
79 new PrefStoreClient(std::move(pref_store_it->second))); | |
80 } else { | |
81 return nullptr; | |
82 } | |
83 } | |
84 | |
85 ConnectionBarrier::ConnectionBarrier( | |
86 scoped_refptr<PrefRegistry> pref_registry, | |
87 scoped_refptr<PersistentPrefStore> persistent_pref_store, | |
88 ConnectCallback callback) | |
89 : pref_registry_(std::move(pref_registry)), | |
90 persistent_pref_store_(std::move(persistent_pref_store)), | |
91 callback_(std::move(callback)) {} | |
92 | |
93 void ConnectionBarrier::OnConnect( | |
94 scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>> | |
95 connector_ptr, | |
96 scoped_refptr<PrefRegistry> pref_registry, | |
97 std::unordered_map<PrefValueStore::PrefStoreType, | |
98 mojom::PrefStoreConnectionPtr> connections) { | |
99 scoped_refptr<PrefStore> managed_prefs = | |
100 CreatePrefStore(PrefValueStore::MANAGED_STORE, &connections); | |
101 scoped_refptr<PrefStore> supervised_user_prefs = | |
102 CreatePrefStore(PrefValueStore::SUPERVISED_USER_STORE, &connections); | |
103 scoped_refptr<PrefStore> extension_prefs = | |
104 CreatePrefStore(PrefValueStore::EXTENSION_STORE, &connections); | |
105 scoped_refptr<PrefStore> command_line_prefs = | |
106 CreatePrefStore(PrefValueStore::COMMAND_LINE_STORE, &connections); | |
107 scoped_refptr<PrefStore> recommended_prefs = | |
108 CreatePrefStore(PrefValueStore::RECOMMENDED_STORE, &connections); | |
109 scoped_refptr<PrefStore> default_prefs = | |
110 CreatePrefStore(PrefValueStore::DEFAULT_STORE, &connections); | |
111 PrefNotifierImpl* pref_notifier = new PrefNotifierImpl(); | |
112 auto* pref_value_store = new PrefValueStore( | |
113 managed_prefs.get(), supervised_user_prefs.get(), extension_prefs.get(), | |
114 command_line_prefs.get(), persistent_pref_store_.get(), | |
115 recommended_prefs.get(), default_prefs.get(), pref_notifier); | |
116 base::ResetAndReturn(&callback_) | |
117 .Run(base::MakeUnique<::PrefService>( | |
118 pref_notifier, pref_value_store, persistent_pref_store_.get(), | |
119 pref_registry_.get(), base::Bind(&DoNothingHandleReadError), true)); | |
120 connector_ptr->reset(); | |
121 } | |
122 | |
123 void ConnectionBarrier::OnConnectError( | |
124 scoped_refptr<RefCountedInterfacePtr<mojom::PrefStoreConnector>> | |
125 connector_ptr) { | |
126 callback_.Run(nullptr); | |
127 connector_ptr->reset(); | |
128 } | |
129 | |
130 // static | |
131 void ConnectionBarrier::Create(service_manager::Connector* connector, | |
132 scoped_refptr<PrefRegistry> pref_registry, | |
133 ConnectCallback callback) { | |
134 // Connect to user pref store. | |
135 mojom::PersistentPrefStoreConnectorPtr persistent_connector_ptr; | |
136 connector->BindInterface(mojom::kPrefStoreServiceName, | |
137 &persistent_connector_ptr); | |
138 auto barrier = make_scoped_refptr(new ConnectionBarrier( | |
139 std::move(pref_registry), | |
140 make_scoped_refptr( | |
141 new PersistentPrefStoreClient(std::move(persistent_connector_ptr))), | |
142 std::move(callback))); | |
143 | |
144 // Connect to all other pref stores. | |
145 auto connector_ptr = make_scoped_refptr( | |
146 new RefCountedInterfacePtr<mojom::PrefStoreConnector>()); | |
147 connector->BindInterface(mojom::kPrefStoreServiceName, &connector_ptr->get()); | |
148 connector_ptr->get().set_connection_error_handler( | |
149 base::Bind(&ConnectionBarrier::OnConnectError, barrier, connector_ptr)); | |
150 connector_ptr->get()->Connect(base::Bind(&ConnectionBarrier::OnConnect, | |
151 barrier, connector_ptr, | |
152 std::move(pref_registry))); | |
153 } | |
154 | |
155 } // namespace | |
156 | |
157 void ConnectToPrefService(service_manager::Connector* connector, | |
158 scoped_refptr<PrefRegistry> pref_registry, | |
159 const ConnectCallback& callback) { | |
160 ConnectionBarrier::Create(connector, std::move(pref_registry), callback); | |
161 } | |
162 | |
163 } // namespace prefs | |
OLD | NEW |