| OLD | NEW |
| 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 Loading... |
| 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 |
| OLD | NEW |