Index: services/service_manager/service_manager.cc |
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc |
index 73f76e9171a04a08027402dade5c3b04a823b3c9..63a0d7c487a7b22bf06e1f7708fed8e498a9d791 100644 |
--- a/services/service_manager/service_manager.cc |
+++ b/services/service_manager/service_manager.cc |
@@ -47,21 +47,6 @@ |
"service_manager:instance_per_child"; |
const char kCapability_ServiceManager[] = "service_manager:service_manager"; |
-bool Succeeded(mojom::ConnectResult result) { |
- return result == mojom::ConnectResult::SUCCEEDED; |
-} |
- |
-void RunCallback(ConnectParams* params, |
- mojom::ConnectResult result, |
- const std::string& user_id) { |
- if (!params->connect_callback().is_null()) { |
- params->connect_callback().Run(result, user_id); |
- return; |
- } |
- if (!params->bind_interface_callback().is_null()) |
- params->bind_interface_callback().Run(result, user_id); |
-} |
- |
} // namespace |
Identity CreateServiceManagerIdentity() { |
@@ -140,19 +125,18 @@ |
Stop(); |
} |
- bool OnConnect(std::unique_ptr<ConnectParams>* in_params) { |
+ bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { |
if (!service_.is_bound()) |
return false; |
- std::unique_ptr<ConnectParams> params(std::move(*in_params)); |
+ std::unique_ptr<ConnectParams> params(std::move(*connect_params)); |
if (!params->connect_callback().is_null()) { |
params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
identity_.user_id()); |
} |
InterfaceProviderSpecMap specs; |
- Instance* source = |
- service_manager_->GetExistingInstance(params->source()); |
+ Instance* source = service_manager_->GetExistingInstance(params->source()); |
if (source) |
specs = source->interface_provider_specs_; |
@@ -161,48 +145,6 @@ |
params->TakeRemoteInterfaces(), |
base::Bind(&Instance::OnConnectComplete, |
base::Unretained(this))); |
- return true; |
- } |
- |
- bool OnBindInterface(std::unique_ptr<ConnectParams>* in_params) { |
- if (!service_.is_bound()) |
- return false; |
- |
- std::unique_ptr<ConnectParams> params(std::move(*in_params)); |
- InterfaceProviderSpecMap source_specs; |
- InterfaceProviderSpec source_connection_spec; |
- Instance* source = |
- service_manager_->GetExistingInstance(params->source()); |
- if (source) { |
- source_specs = source->interface_provider_specs_; |
- source_connection_spec = source->GetConnectionSpec(); |
- } |
- |
- InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, |
- identity_, |
- GetConnectionSpec()); |
- bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || |
- exposed.count(params->interface_name()) > 0; |
- if (!allowed) { |
- std::stringstream ss; |
- ss << "Connection InterfaceProviderSpec prevented service: " |
- << params->source().name() << " from binding interface: " |
- << params->interface_name() << " exposed by: " << identity_.name(); |
- LOG(ERROR) << ss.str(); |
- params->bind_interface_callback().Run(mojom::ConnectResult::ACCESS_DENIED, |
- identity_.user_id()); |
- return false; |
- } |
- |
- params->bind_interface_callback().Run(mojom::ConnectResult::SUCCEEDED, |
- identity_.user_id()); |
- |
- pending_service_connections_++; |
- service_->OnBindInterface( |
- ServiceInfo(params->source(), source_specs), |
- params->interface_name(), |
- params->TakeInterfaceRequestPipe(), |
- base::Bind(&Instance::OnConnectComplete, base::Unretained(this))); |
return true; |
} |
@@ -287,65 +229,72 @@ |
// mojom::Connector implementation: |
void StartService( |
- const Identity& in_target, |
+ const Identity& target, |
mojo::ScopedMessagePipeHandle service_handle, |
mojom::PIDReceiverRequest pid_receiver_request) override { |
- Identity target = in_target; |
- mojom::ConnectResult result = |
- ValidateConnectParams(&target, nullptr, nullptr); |
- if (!Succeeded(result)) |
- return; |
- |
- std::unique_ptr<ConnectParams> params(new ConnectParams); |
- params->set_source(identity_); |
- params->set_target(target); |
- |
mojom::ServicePtr service; |
service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); |
- params->set_client_process_info(std::move(service), |
- std::move(pid_receiver_request)); |
- service_manager_->Connect( |
- std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
- } |
- |
- void Connect(const service_manager::Identity& in_target, |
+ ConnectImpl( |
+ target, |
+ mojom::InterfaceProviderRequest(), |
+ std::move(service), |
+ std::move(pid_receiver_request), |
+ base::Bind( |
+ &service_manager::ServiceManager::Instance::EmptyConnectCallback, |
+ weak_factory_.GetWeakPtr())); |
+ } |
+ |
+ void Connect(const service_manager::Identity& target, |
mojom::InterfaceProviderRequest remote_interfaces, |
const ConnectCallback& callback) override { |
+ ConnectImpl(target, std::move(remote_interfaces), mojom::ServicePtr(), |
+ mojom::PIDReceiverRequest(), callback); |
+ } |
+ |
+ void BindInterface(const service_manager::Identity& target, |
+ const std::string& interface_name, |
+ mojo::ScopedMessagePipeHandle interface_pipe, |
+ const BindInterfaceCallback& callback) override { |
+ mojom::InterfaceProviderPtr remote_interfaces; |
+ ConnectImpl( |
+ target, |
+ MakeRequest(&remote_interfaces), |
+ mojom::ServicePtr(), |
+ mojom::PIDReceiverRequest(), |
+ base::Bind( |
+ &service_manager::ServiceManager::Instance::BindCallbackWrapper, |
+ weak_factory_.GetWeakPtr(), |
+ callback)); |
+ remote_interfaces->GetInterface(interface_name, std::move(interface_pipe)); |
+ // TODO(beng): Rather than just forwarding thru to InterfaceProvider, do |
+ // manifest policy intersection here. |
+ } |
+ |
+ void ConnectImpl(const service_manager::Identity& in_target, |
+ mojom::InterfaceProviderRequest remote_interfaces, |
+ mojom::ServicePtr service, |
+ mojom::PIDReceiverRequest pid_receiver_request, |
+ const ConnectCallback& callback) { |
Identity target = in_target; |
- mojom::ConnectResult result = |
- ValidateConnectParams(&target, nullptr, nullptr); |
- if (!Succeeded(result)) { |
- callback.Run(result, mojom::kInheritUserID); |
+ if (target.user_id() == mojom::kInheritUserID) |
+ target.set_user_id(identity_.user_id()); |
+ |
+ if (!ValidateIdentity(target, callback)) |
return; |
- } |
+ if (!ValidateClientProcessInfo(&service, &pid_receiver_request, target, |
+ callback)) { |
+ return; |
+ } |
+ if (!ValidateConnectionSpec(target, callback)) |
+ return; |
std::unique_ptr<ConnectParams> params(new ConnectParams); |
params->set_source(identity_); |
params->set_target(target); |
params->set_remote_interfaces(std::move(remote_interfaces)); |
+ params->set_client_process_info(std::move(service), |
+ std::move(pid_receiver_request)); |
params->set_connect_callback(callback); |
- service_manager_->Connect( |
- std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
- } |
- |
- void BindInterface(const service_manager::Identity& in_target, |
- const std::string& interface_name, |
- mojo::ScopedMessagePipeHandle interface_pipe, |
- const BindInterfaceCallback& callback) override { |
- Identity target = in_target; |
- mojom::ConnectResult result = |
- ValidateConnectParams(&target, nullptr, nullptr); |
- if (!Succeeded(result)) { |
- callback.Run(result, mojom::kInheritUserID); |
- return; |
- } |
- |
- std::unique_ptr<ConnectParams> params(new ConnectParams); |
- params->set_source(identity_); |
- params->set_target(target); |
- params->set_interface_request_info(interface_name, |
- std::move(interface_pipe)); |
- params->set_bind_interface_callback(callback); |
service_manager_->Connect( |
std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
} |
@@ -372,66 +321,61 @@ |
service_manager_->AddListener(std::move(listener)); |
} |
- mojom::ConnectResult ValidateConnectParams( |
- Identity* target, |
- mojom::ServicePtr* service, |
- mojom::PIDReceiverRequest* pid_receiver_request) { |
- if (target->user_id() == mojom::kInheritUserID) |
- target->set_user_id(identity_.user_id()); |
- |
- mojom::ConnectResult result = ValidateIdentity(*target); |
- if (!Succeeded(result)) |
- return result; |
- |
- result = ValidateClientProcessInfo(service, pid_receiver_request, *target); |
- if (!Succeeded(result)) |
- return result; |
- return ValidateConnectionSpec(*target); |
- } |
- |
- mojom::ConnectResult ValidateIdentity(const Identity& identity) { |
+ bool ValidateIdentity(const Identity& identity, |
+ const ConnectCallback& callback) { |
if (identity.name().empty()) { |
LOG(ERROR) << "Error: empty service name."; |
- return mojom::ConnectResult::INVALID_ARGUMENT; |
+ callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
+ mojom::kInheritUserID); |
+ return false; |
} |
if (!base::IsValidGUID(identity.user_id())) { |
LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); |
- return mojom::ConnectResult::INVALID_ARGUMENT; |
- } |
- return mojom::ConnectResult::SUCCEEDED; |
- } |
- |
- mojom::ConnectResult ValidateClientProcessInfo( |
+ callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
+ mojom::kInheritUserID); |
+ return false; |
+ } |
+ return true; |
+ } |
+ |
+ bool ValidateClientProcessInfo( |
mojom::ServicePtr* service, |
mojom::PIDReceiverRequest* pid_receiver_request, |
- const Identity& target) { |
- if (service && pid_receiver_request && |
- (service->is_bound() || pid_receiver_request->is_pending())) { |
+ const Identity& target, |
+ const ConnectCallback& callback) { |
+ if (service->is_bound() || pid_receiver_request->is_pending()) { |
if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { |
LOG(ERROR) << "Instance: " << identity_.name() << " attempting " |
<< "to register an instance for a process it created for " |
<< "target: " << target.name() << " without the " |
<< "service_manager{client_process} capability " |
<< "class."; |
- return mojom::ConnectResult::ACCESS_DENIED; |
+ callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
+ mojom::kInheritUserID); |
+ return false; |
} |
if (!service->is_bound() || !pid_receiver_request->is_pending()) { |
LOG(ERROR) << "Must supply both service AND " |
<< "pid_receiver_request when sending client process info"; |
- return mojom::ConnectResult::INVALID_ARGUMENT; |
+ callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
+ mojom::kInheritUserID); |
+ return false; |
} |
if (service_manager_->GetExistingInstance(target)) { |
LOG(ERROR) << "Cannot client process matching existing identity:" |
<< "Name: " << target.name() << " User: " |
<< target.user_id() << " Instance: " << target.instance(); |
- return mojom::ConnectResult::INVALID_ARGUMENT; |
+ callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
+ mojom::kInheritUserID); |
+ return false; |
} |
} |
- return mojom::ConnectResult::SUCCEEDED; |
- } |
- |
- mojom::ConnectResult ValidateConnectionSpec(const Identity& target) { |
+ return true; |
+ } |
+ |
+ bool ValidateConnectionSpec(const Identity& target, |
+ const ConnectCallback& callback) { |
InterfaceProviderSpec connection_spec = GetConnectionSpec(); |
// TODO(beng): Need to do the following additional policy validation of |
// whether this instance is allowed to connect using: |
@@ -444,7 +388,9 @@ |
<< " attempting to connect to: " << target.name() |
<< " as: " << target.user_id() << " without " |
<< " the service:service_manager{user_id} capability."; |
- return mojom::ConnectResult::ACCESS_DENIED; |
+ callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
+ mojom::kInheritUserID); |
+ return false; |
} |
if (!target.instance().empty() && |
target.instance() != target.name() && |
@@ -454,17 +400,19 @@ |
<< " using Instance name: " << target.instance() |
<< " without the " |
<< "service_manager{instance_name} capability."; |
- return mojom::ConnectResult::ACCESS_DENIED; |
+ callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); |
+ return false; |
} |
if (allow_any_application_ || |
connection_spec.requires.find(target.name()) != |
connection_spec.requires.end()) { |
- return mojom::ConnectResult::SUCCEEDED; |
+ return true; |
} |
LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " |
<< identity_.name() << " to: " << target.name(); |
- return mojom::ConnectResult::ACCESS_DENIED; |
+ callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); |
+ return false; |
} |
uint32_t GenerateUniqueID() const { |
@@ -834,14 +782,7 @@ |
bool ServiceManager::ConnectToExistingInstance( |
std::unique_ptr<ConnectParams>* params) { |
Instance* instance = GetExistingInstance((*params)->target()); |
- if (instance) { |
- if ((*params)->HasInterfaceRequestInfo()) { |
- instance->OnBindInterface(params); |
- return true; |
- } |
- return instance->OnConnect(params); |
- } |
- return false; |
+ return instance && instance->ConnectToService(params); |
} |
ServiceManager::Instance* ServiceManager::CreateInstance( |
@@ -927,7 +868,10 @@ |
// If name resolution failed, we drop the connection. |
if (!result) { |
LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); |
- RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); |
+ if (!params->connect_callback().is_null()) { |
+ params->connect_callback().Run( |
+ mojom::ConnectResult::INVALID_ARGUMENT, ""); |
+ } |
return; |
} |
@@ -997,7 +941,8 @@ |
LOG(ERROR) |
<< "Error: The catalog was unable to read a manifest for service \"" |
<< result->name << "\"."; |
- RunCallback(params.get(), mojom::ConnectResult::ACCESS_DENIED, ""); |
+ if (!params->connect_callback().is_null()) |
+ params->connect_callback().Run(mojom::ConnectResult::ACCESS_DENIED, ""); |
return; |
} |
@@ -1035,19 +980,18 @@ |
if (!instance->StartWithFilePath(package_path)) { |
OnInstanceError(instance); |
- RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); |
+ if (!params->connect_callback().is_null()) { |
+ params->connect_callback().Run( |
+ mojom::ConnectResult::INVALID_ARGUMENT, ""); |
+ } |
return; |
} |
} |
} |
// Now that the instance has a Service, we can connect to it. |
- if (params->HasInterfaceRequestInfo()) { |
- instance->OnBindInterface(¶ms); |
- } else { |
- bool connected = instance->OnConnect(¶ms); |
- DCHECK(connected); |
- } |
+ bool connected = instance->ConnectToService(¶ms); |
+ DCHECK(connected); |
} |
base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |