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

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

Issue 2446313003: Revise InterfaceRegistry API to support filtering interfaces @ Bind() time. (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
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"
11 11
12 namespace service_manager { 12 namespace service_manager {
13 namespace {
13 14
14 InterfaceRegistry::InterfaceRegistry() 15 // Returns the set of capabilities required from the target.
15 : binding_(this), allow_all_interfaces_(true), weak_factory_(this) {} 16 CapabilitySet GetRequestedCapabilities(const InterfaceProviderSpec& source_spec,
17 const Identity& target) {
18 CapabilitySet capabilities;
19
20 // Start by looking for specs specific to the supplied identity.
21 auto it = source_spec.requires.find(target.name());
22 if (it != source_spec.requires.end()) {
23 std::copy(it->second.begin(), it->second.end(),
24 std::inserter(capabilities, capabilities.begin()));
25 }
26
27 // Apply wild card rules too.
28 it = source_spec.requires.find("*");
29 if (it != source_spec.requires.end()) {
30 std::copy(it->second.begin(), it->second.end(),
31 std::inserter(capabilities, capabilities.begin()));
32 }
33 return capabilities;
34 }
35
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.
38 InterfaceSet GetAllowedInterfaces(
39 const InterfaceProviderSpec& source_spec,
40 const Identity& target,
41 const InterfaceProviderSpec& target_spec) {
42 InterfaceSet allowed_interfaces;
43 // TODO(beng): remove this once we can assert that an InterfaceRegistry must
44 // always be constructed with a valid identity.
45 if (!target.IsValid()) {
46 allowed_interfaces.insert("*");
47 return allowed_interfaces;
48 }
49 CapabilitySet capabilities = GetRequestedCapabilities(source_spec, target);
50 for (const auto& capability : capabilities) {
51 auto it = target_spec.provides.find(capability);
52 if (it != target_spec.provides.end()) {
53 for (const auto& interface_name : it->second)
54 allowed_interfaces.insert(interface_name);
55 }
56 }
57 return allowed_interfaces;
58 }
59
60
61 } // namespace
16 62
17 InterfaceRegistry::InterfaceRegistry( 63 InterfaceRegistry::InterfaceRegistry(
18 const Identity& local_identity, 64 const Identity& identity,
19 const Identity& remote_identity, 65 const InterfaceProviderSpec& interface_provider_spec)
20 const InterfaceSet& allowed_interfaces)
21 : binding_(this), 66 : binding_(this),
22 local_identity_(local_identity), 67 identity_(identity),
23 remote_identity_(remote_identity), 68 interface_provider_spec_(interface_provider_spec),
24 allowed_interfaces_(allowed_interfaces),
25 allow_all_interfaces_(allowed_interfaces_.size() == 1 &&
26 allowed_interfaces_.count("*") == 1),
27 weak_factory_(this) {} 69 weak_factory_(this) {}
28 70
29 InterfaceRegistry::~InterfaceRegistry() {} 71 InterfaceRegistry::~InterfaceRegistry() {}
30 72
31 void InterfaceRegistry::Bind( 73 void InterfaceRegistry::Bind(
32 mojom::InterfaceProviderRequest local_interfaces_request) { 74 mojom::InterfaceProviderRequest local_interfaces_request,
75 const Identity& remote_identity,
76 const InterfaceProviderSpec& remote_interface_provider_spec) {
33 DCHECK(!binding_.is_bound()); 77 DCHECK(!binding_.is_bound());
78 remote_identity_ = remote_identity;
79 allowed_interfaces_ = GetAllowedInterfaces(remote_interface_provider_spec,
80 identity_,
81 interface_provider_spec_);
82 allow_all_interfaces_ =
83 allowed_interfaces_.size() == 1 && allowed_interfaces_.count("*") == 1;
84 if (!allow_all_interfaces_) {
85 for (auto it = name_to_binder_.begin(); it != name_to_binder_.end(); ++it) {
86 if (allowed_interfaces_.count(it->first) == 0)
87 name_to_binder_.erase(it);
88 }
89 }
34 binding_.Bind(std::move(local_interfaces_request)); 90 binding_.Bind(std::move(local_interfaces_request));
35 } 91 }
36 92
37 base::WeakPtr<InterfaceRegistry> InterfaceRegistry::GetWeakPtr() { 93 base::WeakPtr<InterfaceRegistry> InterfaceRegistry::GetWeakPtr() {
38 return weak_factory_.GetWeakPtr(); 94 return weak_factory_.GetWeakPtr();
39 } 95 }
40 96
41 bool InterfaceRegistry::AddInterface( 97 bool InterfaceRegistry::AddInterface(
42 const std::string& name, 98 const std::string& name,
43 const base::Callback<void(mojo::ScopedMessagePipeHandle)>& callback, 99 const base::Callback<void(mojo::ScopedMessagePipeHandle)>& callback,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 147
92 auto iter = name_to_binder_.find(interface_name); 148 auto iter = name_to_binder_.find(interface_name);
93 if (iter != name_to_binder_.end()) { 149 if (iter != name_to_binder_.end()) {
94 iter->second->BindInterface(remote_identity_, 150 iter->second->BindInterface(remote_identity_,
95 interface_name, 151 interface_name,
96 std::move(handle)); 152 std::move(handle));
97 } else if (!CanBindRequestForInterface(interface_name)) { 153 } else if (!CanBindRequestForInterface(interface_name)) {
98 std::stringstream ss; 154 std::stringstream ss;
99 ss << "Capability spec prevented service " << remote_identity_.name() 155 ss << "Capability spec prevented service " << remote_identity_.name()
100 << " from binding interface: " << interface_name 156 << " from binding interface: " << interface_name
101 << " exposed by: " << local_identity_.name(); 157 << " exposed by: " << identity_.name();
102 LOG(ERROR) << ss.str(); 158 LOG(ERROR) << ss.str();
103 mojo::ReportBadMessage(ss.str()); 159 mojo::ReportBadMessage(ss.str());
104 } else if (!default_binder_.is_null()) { 160 } else if (!default_binder_.is_null()) {
105 default_binder_.Run(interface_name, std::move(handle)); 161 default_binder_.Run(interface_name, std::move(handle));
106 } else { 162 } else {
107 LOG(ERROR) << "Failed to locate a binder for interface: " << interface_name 163 LOG(ERROR) << "Failed to locate a binder for interface: " << interface_name
108 << " requested by: " << remote_identity_.name() 164 << " requested by: " << remote_identity_.name()
109 << " exposed by: " << local_identity_.name(); 165 << " exposed by: " << identity_.name();
110 } 166 }
111 } 167 }
112 168
113 bool InterfaceRegistry::SetInterfaceBinderForName( 169 bool InterfaceRegistry::SetInterfaceBinderForName(
114 std::unique_ptr<InterfaceBinder> binder, 170 std::unique_ptr<InterfaceBinder> binder,
115 const std::string& interface_name) { 171 const std::string& interface_name) {
116 if (CanBindRequestForInterface(interface_name)) { 172 if (CanBindRequestForInterface(interface_name)) {
117 RemoveInterface(interface_name); 173 RemoveInterface(interface_name);
118 name_to_binder_[interface_name] = std::move(binder); 174 name_to_binder_[interface_name] = std::move(binder);
119 return true; 175 return true;
120 } 176 }
121 return false; 177 return false;
122 } 178 }
123 179
124 bool InterfaceRegistry::CanBindRequestForInterface( 180 bool InterfaceRegistry::CanBindRequestForInterface(
125 const std::string& interface_name) const { 181 const std::string& interface_name) const {
182 // Any interface may be registered before the registry is bound to a pipe. At
183 // bind time, the interfaces exposed will be intersected with the requirements
184 // of the source.
185 if (!binding_.is_bound())
186 return true;
126 return allow_all_interfaces_ || allowed_interfaces_.count(interface_name); 187 return allow_all_interfaces_ || allowed_interfaces_.count(interface_name);
127 } 188 }
128 189
129 } // namespace service_manager 190 } // namespace service_manager
OLDNEW
« no previous file with comments | « services/service_manager/public/cpp/lib/identity.cc ('k') | services/service_manager/public/cpp/lib/service_context.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698