Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: services/service_manager/public/cpp/lib/interface_registry.cc

Issue 2457493004: Cleanup InterfaceRegistry + adds Serialize() (Closed)
Patch Set: . Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « services/service_manager/public/cpp/interface_registry.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "services/service_manager/public/cpp/interface_registry.h" 5 #include "services/service_manager/public/cpp/interface_registry.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "mojo/public/cpp/bindings/message.h" 9 #include "mojo/public/cpp/bindings/message.h"
10 #include "services/service_manager/public/cpp/connection.h" 10 #include "services/service_manager/public/cpp/connection.h"
(...skipping 17 matching lines...) Expand all
28 it = source_spec.requires.find("*"); 28 it = source_spec.requires.find("*");
29 if (it != source_spec.requires.end()) { 29 if (it != source_spec.requires.end()) {
30 std::copy(it->second.begin(), it->second.end(), 30 std::copy(it->second.begin(), it->second.end(),
31 std::inserter(capabilities, capabilities.begin())); 31 std::inserter(capabilities, capabilities.begin()));
32 } 32 }
33 return capabilities; 33 return capabilities;
34 } 34 }
35 35
36 // Generates a single set of interfaces that is the union of all interfaces 36 // Generates a single set of interfaces that is the union of all interfaces
37 // exposed by the target for the capabilities requested by the source. 37 // exposed by the target for the capabilities requested by the source.
38 InterfaceSet GetAllowedInterfaces( 38 InterfaceSet GetInterfacesToExpose(
39 const InterfaceProviderSpec& source_spec, 39 const InterfaceProviderSpec& source_spec,
40 const Identity& target, 40 const Identity& target,
41 const InterfaceProviderSpec& target_spec) { 41 const InterfaceProviderSpec& target_spec) {
42 InterfaceSet allowed_interfaces; 42 InterfaceSet exposed_interfaces;
43 // TODO(beng): remove this once we can assert that an InterfaceRegistry must 43 // TODO(beng): remove this once we can assert that an InterfaceRegistry must
44 // always be constructed with a valid identity. 44 // always be constructed with a valid identity.
45 if (!target.IsValid()) { 45 if (!target.IsValid()) {
46 allowed_interfaces.insert("*"); 46 exposed_interfaces.insert("*");
47 return allowed_interfaces; 47 return exposed_interfaces;
48 } 48 }
49 CapabilitySet capabilities = GetRequestedCapabilities(source_spec, target); 49 CapabilitySet capabilities = GetRequestedCapabilities(source_spec, target);
50 for (const auto& capability : capabilities) { 50 for (const auto& capability : capabilities) {
51 auto it = target_spec.provides.find(capability); 51 auto it = target_spec.provides.find(capability);
52 if (it != target_spec.provides.end()) { 52 if (it != target_spec.provides.end()) {
53 for (const auto& interface_name : it->second) 53 for (const auto& interface_name : it->second)
54 allowed_interfaces.insert(interface_name); 54 exposed_interfaces.insert(interface_name);
55 } 55 }
56 } 56 }
57 return allowed_interfaces; 57 return exposed_interfaces;
58 } 58 }
59 59
60 void SerializeIdentity(const Identity& identity, std::stringstream* stream) {
61 *stream << identity.name() << "@" << identity.instance() << " run as: "
62 << identity.user_id();
63 }
64
65 void SerializeSpec(const InterfaceProviderSpec& spec,
66 std::stringstream* stream) {
67 *stream << " Providing:\n";
68 for (const auto& entry : spec.provides) {
69 *stream << " capability: " << entry.first << " containing interfaces:\n";
70 for (const auto& interface_name : entry.second)
71 *stream << " " << interface_name << "\n";
72 }
73 *stream << "\n Requiring:\n";
74 for (const auto& entry : spec.requires) {
75 *stream << " From: " << entry.first << ":\n";
76 for (const auto& capability_name : entry.second)
77 *stream << " " << capability_name << "\n";
78 }
79 }
60 80
61 } // namespace 81 } // namespace
62 82
63 InterfaceRegistry::InterfaceRegistry(const std::string& name) 83 InterfaceRegistry::InterfaceRegistry(const std::string& name)
64 : binding_(this), 84 : binding_(this),
65 name_(name), 85 name_(name),
66 weak_factory_(this) {} 86 weak_factory_(this) {}
67 InterfaceRegistry::~InterfaceRegistry() {} 87 InterfaceRegistry::~InterfaceRegistry() {}
68 88
69 void InterfaceRegistry::Bind( 89 void InterfaceRegistry::Bind(
70 mojom::InterfaceProviderRequest local_interfaces_request, 90 mojom::InterfaceProviderRequest local_interfaces_request,
71 const Identity& local_identity, 91 const Identity& local_identity,
72 const InterfaceProviderSpec& local_interface_provider_spec, 92 const InterfaceProviderSpec& local_interface_provider_spec,
73 const Identity& remote_identity, 93 const Identity& remote_identity,
74 const InterfaceProviderSpec& remote_interface_provider_spec) { 94 const InterfaceProviderSpec& remote_interface_provider_spec) {
75 DCHECK(!binding_.is_bound()); 95 DCHECK(!binding_.is_bound());
76 identity_ = local_identity; 96 local_identity_ = local_identity;
77 interface_provider_spec_ = local_interface_provider_spec; 97 local_interface_provider_spec_ = local_interface_provider_spec;
78 remote_identity_ = remote_identity; 98 remote_identity_ = remote_identity;
79 allowed_interfaces_ = GetAllowedInterfaces(remote_interface_provider_spec, 99 remote_interface_provider_spec_ = remote_interface_provider_spec;
80 identity_, 100 RebuildExposedInterfaces();
81 interface_provider_spec_); 101 binding_.Bind(std::move(local_interfaces_request));
82 allow_all_interfaces_ = 102 }
83 allowed_interfaces_.size() == 1 && allowed_interfaces_.count("*") == 1; 103
84 if (!allow_all_interfaces_) { 104 void InterfaceRegistry::Serialize(std::stringstream* stream) {
85 for (auto it = name_to_binder_.begin(); it != name_to_binder_.end();) { 105 *stream << "\n\nInterfaceRegistry(" << name_ << "):\n";
86 if (allowed_interfaces_.count(it->first) == 0) 106 if (!binding_.is_bound()) {
87 it = name_to_binder_.erase(it); 107 *stream << "\n --> InterfaceRegistry is not yet bound to a pipe.\n\n";
88 else 108 return;
89 ++it;
90 }
91 } 109 }
92 binding_.Bind(std::move(local_interfaces_request)); 110
111 *stream << "Owned by:\n ";
112 SerializeIdentity(local_identity_, stream);
113 *stream << "\n\n";
114 SerializeSpec(local_interface_provider_spec_, stream);
115
116 *stream << "\n";
117
118 *stream << "Bound to:\n ";
119 SerializeIdentity(remote_identity_, stream);
120 *stream << "\n\n";
121 SerializeSpec(remote_interface_provider_spec_, stream);
122
123 *stream << "\nBinders registered for:\n";
124 bool found_exposed = false;
125 for (const auto& entry : name_to_binder_) {
126 bool exposed = exposed_interfaces_.count(entry.first) > 0;
127 found_exposed |= exposed;
128 *stream << " " << (exposed ? "* " : " ") << entry.first << "\n";
129 }
130 if (found_exposed)
131 *stream << "\n * - denotes an interface exposed to remote per policy.\n";
132
133 *stream << "\n\n";
134 if (expose_all_interfaces_)
135 *stream << "All interfaces exposed.\n\n";
93 } 136 }
94 137
95 base::WeakPtr<InterfaceRegistry> InterfaceRegistry::GetWeakPtr() { 138 base::WeakPtr<InterfaceRegistry> InterfaceRegistry::GetWeakPtr() {
96 return weak_factory_.GetWeakPtr(); 139 return weak_factory_.GetWeakPtr();
97 } 140 }
98 141
99 bool InterfaceRegistry::AddInterface( 142 bool InterfaceRegistry::AddInterface(
100 const std::string& name, 143 const std::string& name,
101 const base::Callback<void(mojo::ScopedMessagePipeHandle)>& callback, 144 const base::Callback<void(mojo::ScopedMessagePipeHandle)>& callback,
102 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { 145 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 } 183 }
141 184
142 // mojom::InterfaceProvider: 185 // mojom::InterfaceProvider:
143 void InterfaceRegistry::GetInterface(const std::string& interface_name, 186 void InterfaceRegistry::GetInterface(const std::string& interface_name,
144 mojo::ScopedMessagePipeHandle handle) { 187 mojo::ScopedMessagePipeHandle handle) {
145 if (is_paused_) { 188 if (is_paused_) {
146 pending_interface_requests_.emplace(interface_name, std::move(handle)); 189 pending_interface_requests_.emplace(interface_name, std::move(handle));
147 return; 190 return;
148 } 191 }
149 192
150 auto iter = name_to_binder_.find(interface_name); 193 if (CanBindRequestForInterface(interface_name)) {
151 if (iter != name_to_binder_.end()) { 194 auto iter = name_to_binder_.find(interface_name);
152 iter->second->BindInterface(remote_identity_, 195 if (iter != name_to_binder_.end()) {
153 interface_name, 196 iter->second->BindInterface(remote_identity_,
154 std::move(handle)); 197 interface_name,
155 } else if (!CanBindRequestForInterface(interface_name)) { 198 std::move(handle));
199 } else if (!default_binder_.is_null()) {
200 default_binder_.Run(interface_name, std::move(handle));
201 } else {
202 std::stringstream ss;
203 ss << "Failed to locate a binder for interface: " << interface_name
204 << " requested by: " << remote_identity_.name() << " exposed by: "
205 << local_identity_.name() << " via InterfaceProviderSpec \"" << name_
206 << "\".";
207 Serialize(&ss);
208 LOG(ERROR) << ss.str();
209 }
210 } else {
156 std::stringstream ss; 211 std::stringstream ss;
157 ss << "InterfaceProviderSpec \"" << name_ << "\" prevented service: " 212 ss << "InterfaceProviderSpec \"" << name_ << "\" prevented service: "
158 << remote_identity_.name() << " from binding interface: " 213 << remote_identity_.name() << " from binding interface: "
159 << interface_name << " exposed by: " << identity_.name(); 214 << interface_name << " exposed by: " << local_identity_.name();
215 Serialize(&ss);
160 LOG(ERROR) << ss.str(); 216 LOG(ERROR) << ss.str();
161 mojo::ReportBadMessage(ss.str()); 217 mojo::ReportBadMessage(ss.str());
162 } else if (!default_binder_.is_null()) {
163 default_binder_.Run(interface_name, std::move(handle));
164 } else {
165 LOG(ERROR) << "Failed to locate a binder for interface: " << interface_name
166 << " requested by: " << remote_identity_.name()
167 << " exposed by: " << identity_.name();
168 } 218 }
169 } 219 }
170 220
171 bool InterfaceRegistry::SetInterfaceBinderForName( 221 bool InterfaceRegistry::SetInterfaceBinderForName(
172 std::unique_ptr<InterfaceBinder> binder, 222 std::unique_ptr<InterfaceBinder> binder,
173 const std::string& interface_name) { 223 const std::string& interface_name) {
174 if (CanBindRequestForInterface(interface_name)) { 224 if (CanBindRequestForInterface(interface_name)) {
175 RemoveInterface(interface_name); 225 RemoveInterface(interface_name);
176 name_to_binder_[interface_name] = std::move(binder); 226 name_to_binder_[interface_name] = std::move(binder);
177 return true; 227 return true;
178 } 228 }
179 return false; 229 return false;
180 } 230 }
181 231
182 bool InterfaceRegistry::CanBindRequestForInterface( 232 bool InterfaceRegistry::CanBindRequestForInterface(
183 const std::string& interface_name) const { 233 const std::string& interface_name) const {
184 // Any interface may be registered before the registry is bound to a pipe. At 234 // Any interface may be registered before the registry is bound to a pipe. At
185 // bind time, the interfaces exposed will be intersected with the requirements 235 // bind time, the interfaces exposed will be intersected with the requirements
186 // of the source. 236 // of the source.
187 if (!binding_.is_bound()) 237 if (!binding_.is_bound())
188 return true; 238 return true;
189 return allow_all_interfaces_ || allowed_interfaces_.count(interface_name); 239 return expose_all_interfaces_ || exposed_interfaces_.count(interface_name);
240 }
241
242 void InterfaceRegistry::RebuildExposedInterfaces() {
243 exposed_interfaces_ = GetInterfacesToExpose(remote_interface_provider_spec_,
244 local_identity_,
245 local_interface_provider_spec_);
246 expose_all_interfaces_ =
247 exposed_interfaces_.size() == 1 && exposed_interfaces_.count("*") == 1;
190 } 248 }
191 249
192 } // namespace service_manager 250 } // namespace service_manager
OLDNEW
« no previous file with comments | « services/service_manager/public/cpp/interface_registry.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698