Commit 6d56c5ad authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Reland "[service-manager] Simplify connection logic"

This is a reland of 18526eed

Diff PS3->PS4 is fix for breakage.

Original change's description:
> [service-manager] Simplify connection logic
>
> This reduces the complexity of Service Manager's logic for handling
> interconnection between service instances. Much of the complexity was
> due to connection operations once upon a time being highly
> asynchronous within SM, but that hasn't been the case for a while.
>
> Rather than having ServiceManager::Connect do way too much stuff, it's
> replaced with a simpler and more straightforward
> FindOrCreateMatchingTargetInstance, which does only what the name says.
> Previous work done by Connect() in various edge cases has been moved out
> to its prior call sites, now replaced with calls to FOCMTI.
>
> Bug: 904240
> Change-Id: Ia276f6fa61477ddc141724d30484237498eef070
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1593722
> Reviewed-by: Oksana Zhuravlova <oksamyt@chromium.org>
> Commit-Queue: Ken Rockot <rockot@google.com>
> Cr-Commit-Position: refs/heads/master@{#657401}

Bug: 904240
Change-Id: If07ff20dd8886901013f214f8b51a9e447224189
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1600453Reviewed-by: default avatarOksana Zhuravlova <oksamyt@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#657746}
parent ae8ee33c
......@@ -220,7 +220,7 @@ void ServiceInstance::StartWithRemote(
base::BindOnce(&ServiceInstance::OnStartCompleted,
base::Unretained(this)));
service_manager_->NotifyServiceCreated(this);
service_manager_->NotifyServiceCreated(*this);
}
bool ServiceInstance::StartWithExecutablePath(const base::FilePath& path,
......@@ -246,30 +246,24 @@ bool ServiceInstance::StartWithExecutablePath(const base::FilePath& path,
#endif
}
void ServiceInstance::AuthorizeAndForwardConnectionRequestFromOtherService(
const Identity& source_identity,
bool ServiceInstance::MaybeAcceptConnectionRequest(
const ServiceInstance& source_instance,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojom::BindInterfacePriority priority,
mojom::Connector::BindInterfaceCallback callback) {
ServiceInstance* const source =
service_manager_->GetExistingInstance(source_identity);
if (!source || state_ == mojom::InstanceState::kUnreachable) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED, identity_);
return;
}
mojom::BindInterfacePriority priority) {
if (state_ == mojom::InstanceState::kUnreachable)
return false;
const Manifest& source_manifest = source->manifest();
const Manifest& source_manifest = source_instance.manifest();
const bool bindable_on_any_service = base::ContainsKey(
source_manifest.interfaces_bindable_on_any_service, interface_name);
const bool allowed_by_capabilities =
AllowsInterface(source_manifest.required_capabilities, identity_.name(),
manifest_.exposed_capabilities, interface_name);
if (!bindable_on_any_service && !allowed_by_capabilities) {
ReportBlockedInterface(source_identity.name(), identity_.name(),
ReportBlockedInterface(source_instance.identity().name(), identity_.name(),
interface_name);
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED, identity_);
return;
return false;
}
base::OnceClosure on_bind_interface_complete;
......@@ -280,13 +274,14 @@ void ServiceInstance::AuthorizeAndForwardConnectionRequestFromOtherService(
}
service_remote_->OnBindInterface(
BindSourceInfo(source_identity, GetRequiredCapabilities(
source_manifest.required_capabilities,
BindSourceInfo(
source_instance.identity(),
GetRequiredCapabilities(source_manifest.required_capabilities,
identity_.name())),
interface_name, std::move(receiving_pipe),
std::move(on_bind_interface_complete));
std::move(callback).Run(mojom::ConnectResult::SUCCEEDED, identity_);
return true;
}
void ServiceInstance::Stop() {
......@@ -379,12 +374,12 @@ void ServiceInstance::HandleServiceOrConnectorDisconnection() {
}
}
mojom::ConnectResult ServiceInstance::ValidateConnectionRequestToOtherService(
bool ServiceInstance::CanConnectToOtherInstance(
const ServiceFilter& target_filter,
const base::Optional<std::string>& target_interface_name) {
if (target_filter.service_name().empty()) {
DLOG(ERROR) << "ServiceFilter has no service name.";
return mojom::ConnectResult::INVALID_ARGUMENT;
return false;
}
bool skip_instance_group_check =
......@@ -402,7 +397,7 @@ mojom::ConnectResult ServiceInstance::ValidateConnectionRequestToOtherService(
<< "group " << target_filter.instance_group()->ToString()
<< " without |can_connect_to_instances_in_any_group| set to "
<< "|true|.";
return mojom::ConnectResult::ACCESS_DENIED;
return false;
}
if (target_filter.instance_id() && !target_filter.instance_id()->is_zero() &&
!manifest_.options.can_connect_to_instances_with_any_id) {
......@@ -411,14 +406,14 @@ mojom::ConnectResult ServiceInstance::ValidateConnectionRequestToOtherService(
<< " with instance ID "
<< target_filter.instance_id()->ToString() << " without "
<< "|can_connect_to_instances_with_any_id| set to |true|.";
return mojom::ConnectResult::ACCESS_DENIED;
return false;
}
if (can_contact_all_services_ ||
!manifest_.interfaces_bindable_on_any_service.empty() ||
manifest_.required_capabilities.find(target_filter.service_name()) !=
manifest_.required_capabilities.end()) {
return mojom::ConnectResult::SUCCEEDED;
return true;
}
if (target_interface_name) {
......@@ -428,7 +423,7 @@ mojom::ConnectResult ServiceInstance::ValidateConnectionRequestToOtherService(
ReportBlockedStartService(identity_.name(), target_filter.service_name());
}
return mojom::ConnectResult::ACCESS_DENIED;
return false;
}
void ServiceInstance::BindInterface(
......@@ -437,16 +432,25 @@ void ServiceInstance::BindInterface(
mojo::ScopedMessagePipeHandle receiving_pipe,
mojom::BindInterfacePriority priority,
BindInterfaceCallback callback) {
mojom::ConnectResult result =
ValidateConnectionRequestToOtherService(target_filter, interface_name);
if (result != mojom::ConnectResult::SUCCEEDED) {
std::move(callback).Run(result, base::nullopt);
if (!CanConnectToOtherInstance(target_filter, interface_name)) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED, base::nullopt);
return;
}
ServiceInstance* target_instance =
service_manager_->FindOrCreateMatchingTargetInstance(*this,
target_filter);
bool allowed =
target_instance &&
target_instance->MaybeAcceptConnectionRequest(
*this, interface_name, std::move(receiving_pipe), priority);
if (!allowed) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED, base::nullopt);
return;
}
service_manager_->Connect(target_filter, identity_, interface_name,
std::move(receiving_pipe), priority,
std::move(callback));
std::move(callback).Run(mojom::ConnectResult::SUCCEEDED,
target_instance->identity());
}
void ServiceInstance::QueryService(const std::string& service_name,
......@@ -462,14 +466,22 @@ void ServiceInstance::QueryService(const std::string& service_name,
void ServiceInstance::WarmService(const ServiceFilter& target_filter,
WarmServiceCallback callback) {
mojom::ConnectResult result = ValidateConnectionRequestToOtherService(
target_filter, base::nullopt /* interface_name */);
if (result != mojom::ConnectResult::SUCCEEDED) {
std::move(callback).Run(result, base::nullopt);
if (!CanConnectToOtherInstance(target_filter,
base::nullopt /* interface_name */)) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED, base::nullopt);
return;
}
service_manager_->Connect(target_filter, identity_, std::move(callback));
ServiceInstance* target_instance =
service_manager_->FindOrCreateMatchingTargetInstance(*this,
target_filter);
if (!target_instance) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED, base::nullopt);
return;
}
std::move(callback).Run(mojom::ConnectResult::SUCCEEDED,
target_instance->identity());
}
void ServiceInstance::RegisterServiceInstance(
......@@ -477,6 +489,13 @@ void ServiceInstance::RegisterServiceInstance(
mojo::ScopedMessagePipeHandle service_remote_handle,
mojom::PIDReceiverRequest pid_receiver_request,
RegisterServiceInstanceCallback callback) {
auto target_filter = ServiceFilter::ForExactIdentity(identity);
if (!CanConnectToOtherInstance(target_filter,
base::nullopt /* interface_name */)) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED);
return;
}
mojo::PendingRemote<mojom::Service> service_remote(
std::move(service_remote_handle), 0);
......@@ -495,23 +514,13 @@ void ServiceInstance::RegisterServiceInstance(
return;
}
auto target_filter = ServiceFilter::ForExactIdentity(identity);
mojom::ConnectResult result = ValidateConnectionRequestToOtherService(
target_filter, base::nullopt /* interface_name */);
if (result != mojom::ConnectResult::SUCCEEDED) {
std::move(callback).Run(result);
return;
mojom::ServicePtr service(std::move(service_remote));
if (!service_manager_->RegisterService(identity, std::move(service),
std::move(pid_receiver_request))) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED);
}
service_manager_->Connect(target_filter, identity_, std::move(service_remote),
std::move(pid_receiver_request),
base::BindOnce(
[](RegisterServiceInstanceCallback callback,
mojom::ConnectResult result,
const base::Optional<Identity>& identity) {
std::move(callback).Run(result);
},
std::move(callback)));
std::move(callback).Run(mojom::ConnectResult::SUCCEEDED);
}
void ServiceInstance::Clone(mojom::ConnectorRequest request) {
......
......@@ -73,14 +73,14 @@ class ServiceInstance : public mojom::Connector,
bool StartWithExecutablePath(const base::FilePath& path,
SandboxType sandbox_type);
// Forwards a BindInterface request to the service instance, iff it should be
// allowed based on manifest constraints.
void AuthorizeAndForwardConnectionRequestFromOtherService(
const Identity& source_identity,
// Forwards a BindInterface request from |source_instance| to this instance,
// iff it should be allowed based on manifest constraints. Returns |true| if
// the request was allowed, or |false| otherwise.
bool MaybeAcceptConnectionRequest(
const ServiceInstance& source_instance,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojom::BindInterfacePriority priority,
mojom::Connector::BindInterfaceCallback callback);
mojom::BindInterfacePriority priority);
// Stops receiving any new messages from the service instance and renders the
// instance permanently unreachable. Note that this does NOT make any attempt
......@@ -112,10 +112,11 @@ class ServiceInstance : public mojom::Connector,
// Examines an interface connection request coming from this service instance
// and determines whether it should be allowed to reach any designated target
// instance. A return value of |mojom::ConnectResult::SUCCESS| indicates that
// the request can be processed further. Any other result means the request
// should be rejected.
mojom::ConnectResult ValidateConnectionRequestToOtherService(
// instance. Returns |true| if so, or |false| otherwise.
//
// If |target_interface_name| is null, it is sufficient for this (the source)
// service to have access to *any* arbitrary interface on the target service.
bool CanConnectToOtherInstance(
const ServiceFilter& target_filter,
const base::Optional<std::string>& target_interface_name);
......
......@@ -115,20 +115,14 @@ void ServiceManager::SetInstanceQuitCallback(
instance_quit_callback_ = std::move(callback);
}
void ServiceManager::Connect(
const ServiceFilter& partial_target_filter,
const Identity& source_identity,
const base::Optional<std::string>& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojo::PendingRemote<mojom::Service> service_remote,
mojo::PendingReceiver<mojom::PIDReceiver> pid_receiver,
mojom::BindInterfacePriority priority,
mojom::Connector::BindInterfaceCallback callback) {
ServiceInstance* ServiceManager::FindOrCreateMatchingTargetInstance(
const ServiceInstance& source_instance,
const ServiceFilter& partial_target_filter) {
TRACE_EVENT_INSTANT1("service_manager", "ServiceManager::Connect",
TRACE_EVENT_SCOPE_THREAD, "original_name",
partial_target_filter.service_name());
DCHECK(source_identity.IsValid());
const Identity& source_identity = source_instance.identity();
ServiceFilter target_filter = partial_target_filter;
// If the target filter does not specify an instance group, we assume the
......@@ -140,65 +134,28 @@ void ServiceManager::Connect(
if (!target_filter.instance_id())
target_filter.set_instance_id(base::Token());
if (!service_remote) {
// Connect to an existing matching instance, if possible.
ServiceInstance* instance = instance_registry_.FindMatching(target_filter);
if (instance) {
if (interface_name) {
DCHECK(receiving_pipe.is_valid());
instance->AuthorizeAndForwardConnectionRequestFromOtherService(
source_identity, interface_name.value(), std::move(receiving_pipe),
priority, std::move(callback));
} else {
// This is a StartService request and the instance is already running.
// Make sure the response identity is properly resolved.
std::move(callback).Run(mojom::ConnectResult::SUCCEEDED,
instance->identity());
}
return;
}
// If there was no existing instance but the request specified a specific
// globally unique ID for the target, ignore the request. That instance is
// obviously no longer running.
if (target_filter.globally_unique_id()) {
std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED,
base::nullopt);
return;
}
}
// Beyond this point, in order to fulfill the connection request we need to
// start a new instance of the target service.
// Use an existing instance if possible.
ServiceInstance* target_instance =
instance_registry_.FindMatching(target_filter);
if (target_instance)
return target_instance;
const service_manager::Manifest* manifest =
catalog_.GetManifest(target_filter.service_name());
if (!manifest) {
LOG(ERROR) << "Failed to resolve service name: "
<< target_filter.service_name();
std::move(callback).Run(mojom::ConnectResult::INVALID_ARGUMENT,
base::nullopt);
return;
return nullptr;
}
// Services that use |kSharedAcrossGroups| sharing policy are allowed to
// handle connection requests from instances in any instance group. They also
// run with a synthetic group ID generated below and the group provided by
// |target_filter| is ignored.
// If there was no existing instance but the caller is requesting a specific
// globally unique ID for the target, ignore the request. That instance is
// obviously no longer running, and globally unique IDs are never reused.
if (target_filter.globally_unique_id())
return nullptr;
Identity new_instance_identity;
if (service_remote) {
// This is a service instance registration, so we should use the exact
// Identity given by the caller.
if (!target_filter.globally_unique_id() ||
target_filter.globally_unique_id()->is_zero()) {
std::move(callback).Run(mojom::ConnectResult::INVALID_ARGUMENT,
base::nullopt);
return;
}
new_instance_identity = Identity(
target_filter.service_name(), *target_filter.instance_group(),
*target_filter.instance_id(), *target_filter.globally_unique_id());
} else if (manifest->options.instance_sharing_policy ==
if (manifest->options.instance_sharing_policy ==
Manifest::InstanceSharingPolicy::kSingleton) {
// For singleton instances, we generate a random group ID along with the
// random GUID.
......@@ -207,9 +164,10 @@ void ServiceManager::Connect(
base::Token{}, base::Token::CreateRandom());
} else if (manifest->options.instance_sharing_policy ==
Manifest::InstanceSharingPolicy::kSharedAcrossGroups) {
// For services shared across instance groups, we respect the target
// instance ID but still generate a random group ID along with the random
// GUID.
// Services that use |kSharedAcrossGroups| sharing policy are allowed to
// match ServiceFilters targeting any instance group. They run with a
// random group ID generated here, and the group provided by |target_filter|
// is ignored. The instance ID from |target_filter| is still used.
new_instance_identity =
Identity(target_filter.service_name(), base::Token::CreateRandom(),
*target_filter.instance_id(), base::Token::CreateRandom());
......@@ -221,19 +179,8 @@ void ServiceManager::Connect(
*target_filter.instance_id(), base::Token::CreateRandom());
}
ServiceInstance* instance =
CreateServiceInstance(new_instance_identity, *manifest);
if (service_remote) {
// If this is a service registration via |RegisterService()| or
// |Connector.RegisterServiceInstance()|, we'll have a valid
// |service_remote| already and that's enough to be done.
instance->StartWithRemote(std::move(service_remote),
std::move(pid_receiver));
std::move(callback).Run(mojom::ConnectResult::SUCCEEDED,
instance->identity());
return;
}
DCHECK(!target_instance);
target_instance = CreateServiceInstance(new_instance_identity, *manifest);
const service_manager::Manifest* parent_manifest =
catalog_.GetParentManifest(manifest->service_name);
......@@ -249,7 +196,7 @@ void ServiceManager::Connect(
//
// TODO(https://crbug.com/904240): This is super weird and hard to
// rationalize. Maybe it's the wrong thing to do.
instance->set_identity(
target_instance->set_identity(
Identity(new_instance_identity.name(), *target_filter.instance_group(),
new_instance_identity.instance_id(),
new_instance_identity.globally_unique_id()));
......@@ -262,72 +209,36 @@ void ServiceManager::Connect(
auto pid_receiver_request = mojo::MakeRequest(&pid_receiver);
mojo::PendingRemote<mojom::Service> remote;
CreateServiceWithFactory(factory_filter, target_filter.service_name(),
remote.InitWithNewPipeAndPassReceiver(),
auto* factory = GetServiceFactory(factory_filter);
if (!factory) {
DestroyInstance(target_instance);
return nullptr;
}
factory->CreateService(remote.InitWithNewPipeAndPassReceiver(),
target_filter.service_name(),
std::move(pid_receiver));
instance->StartWithRemote(std::move(remote),
target_instance->StartWithRemote(std::move(remote),
std::move(pid_receiver_request));
} else {
base::FilePath service_exe_root;
CHECK(base::PathService::Get(base::DIR_ASSETS, &service_exe_root));
if (!instance->StartWithExecutablePath(
if (!target_instance->StartWithExecutablePath(
service_exe_root.AppendASCII(manifest->service_name +
kServiceExecutableExtension),
UtilitySandboxTypeFromString(manifest->options.sandbox_type))) {
DestroyInstance(instance);
std::move(callback).Run(mojom::ConnectResult::INVALID_ARGUMENT,
base::nullopt);
return;
}
DestroyInstance(target_instance);
return nullptr;
}
if (interface_name) {
DCHECK(receiving_pipe);
instance->AuthorizeAndForwardConnectionRequestFromOtherService(
source_identity, interface_name.value(), std::move(receiving_pipe),
priority, std::move(callback));
return;
}
std::move(callback).Run(mojom::ConnectResult::SUCCEEDED,
instance->identity());
}
void ServiceManager::Connect(const ServiceFilter& partial_target_filter,
const Identity& source_identity,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojom::BindInterfacePriority priority,
mojom::Connector::BindInterfaceCallback callback) {
Connect(partial_target_filter, source_identity, interface_name,
std::move(receiving_pipe), mojo::NullRemote(), mojo::NullReceiver(),
priority, std::move(callback));
}
void ServiceManager::Connect(const ServiceFilter& partial_target_filter,
const Identity& source_identity,
mojom::Connector::BindInterfaceCallback callback) {
Connect(partial_target_filter, source_identity,
base::nullopt /* interface_name */, mojo::ScopedMessagePipeHandle(),
mojo::NullRemote(), mojo::NullReceiver(),
mojom::BindInterfacePriority::kBestEffort, std::move(callback));
}
void ServiceManager::Connect(
const ServiceFilter& partial_target_filter,
const Identity& source_identity,
mojo::PendingRemote<mojom::Service> service_remote,
mojo::PendingReceiver<mojom::PIDReceiver> pid_receiver,
mojom::Connector::BindInterfaceCallback callback) {
Connect(partial_target_filter, source_identity,
base::nullopt /* interface_name */, mojo::ScopedMessagePipeHandle(),
std::move(service_remote), std::move(pid_receiver),
mojom::BindInterfacePriority::kImportant, std::move(callback));
return target_instance;
}
void ServiceManager::StartService(const std::string& service_name) {
Connect(ServiceFilter::ByNameInGroup(service_name, kSystemInstanceGroup),
GetServiceManagerInstanceIdentity(), base::DoNothing());
FindOrCreateMatchingTargetInstance(
*service_manager_instance_,
ServiceFilter::ByNameInGroup(service_name, kSystemInstanceGroup));
}
bool ServiceManager::QueryCatalog(const std::string& service_name,
......@@ -340,20 +251,30 @@ bool ServiceManager::QueryCatalog(const std::string& service_name,
return true;
}
void ServiceManager::RegisterService(
bool ServiceManager::RegisterService(
const Identity& identity,
mojom::ServicePtr service,
mojom::PIDReceiverRequest pid_receiver_request) {
if (!identity.IsValid())
return false;
const service_manager::Manifest* manifest =
catalog_.GetManifest(identity.name());
if (!manifest) {
LOG(ERROR) << "Failed to resolve service name: " << identity.name();
return false;
}
if (!pid_receiver_request.is_pending()) {
mojo::Remote<mojom::PIDReceiver> pid_receiver;
pid_receiver_request = pid_receiver.BindNewPipeAndPassReceiver();
pid_receiver->SetPID(GetCurrentPid());
}
DCHECK(identity.IsValid());
Connect(ServiceFilter::ForExactIdentity(identity), identity,
service.PassInterface(), std::move(pid_receiver_request),
base::DoNothing());
ServiceInstance* instance = CreateServiceInstance(identity, *manifest);
instance->StartWithRemote(service.PassInterface(),
std::move(pid_receiver_request));
return true;
}
void ServiceManager::MakeInstanceUnreachable(ServiceInstance* instance) {
......@@ -387,8 +308,8 @@ ServiceInstance* ServiceManager::GetExistingInstance(
ServiceFilter::ForExactIdentity(identity));
}
void ServiceManager::NotifyServiceCreated(ServiceInstance* instance) {
mojom::RunningServiceInfoPtr info = instance->CreateRunningServiceInfo();
void ServiceManager::NotifyServiceCreated(const ServiceInstance& instance) {
mojom::RunningServiceInfoPtr info = instance.CreateRunningServiceInfo();
listeners_.ForAllPtrs([&info](mojom::ServiceManagerListener* listener) {
listener->OnServiceCreated(info.Clone());
});
......@@ -443,15 +364,6 @@ void ServiceManager::AddListener(mojom::ServiceManagerListenerPtr listener) {
listeners_.AddPtr(std::move(listener));
}
void ServiceManager::CreateServiceWithFactory(
const ServiceFilter& service_factory_filter,
const std::string& name,
mojom::ServiceRequest request,
mojom::PIDReceiverPtr pid_receiver) {
mojom::ServiceFactory* factory = GetServiceFactory(service_factory_filter);
factory->CreateService(std::move(request), name, std::move(pid_receiver));
}
mojom::ServiceFactory* ServiceManager::GetServiceFactory(
const ServiceFilter& filter) {
auto it = service_factories_.find(filter);
......@@ -459,10 +371,15 @@ mojom::ServiceFactory* ServiceManager::GetServiceFactory(
return it->second.get();
mojom::ServiceFactoryPtr factory;
Connect(filter, GetServiceManagerInstanceIdentity(),
mojom::ServiceFactory::Name_,
ServiceInstance* factory_instance =
FindOrCreateMatchingTargetInstance(*service_manager_instance_, filter);
if (!factory_instance)
return nullptr;
factory_instance->MaybeAcceptConnectionRequest(
*service_manager_instance_, mojom::ServiceFactory::Name_,
mojo::MakeRequest(&factory).PassMessagePipe(),
mojom::BindInterfacePriority::kImportant, base::DoNothing());
mojom::BindInterfacePriority::kImportant);
mojom::ServiceFactory* factory_interface = factory.get();
factory.set_connection_error_handler(base::BindOnce(
......
......@@ -64,7 +64,9 @@ class ServiceManager : public Service {
//
// |pid_receiver_request| may be null, in which case the service manager
// assumes the new service is running in this process.
void RegisterService(const Identity& identity,
//
// Returns |true| if registration succeeded, or |false| otherwise.
bool RegisterService(const Identity& identity,
mojom::ServicePtr service,
mojom::PIDReceiverRequest pid_receiver_request);
......@@ -74,40 +76,17 @@ class ServiceManager : public Service {
const base::Token& instance_group,
std::string* sandbox_type);
// Completes a connection between a source and target application as defined
// by |params|. If no existing instance of the target service is running, one
// will be loaded.
void Connect(const ServiceFilter& partial_target_filter,
const Identity& source_identity,
const base::Optional<std::string>& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojo::PendingRemote<mojom::Service> service_remote,
mojo::PendingReceiver<mojom::PIDReceiver> pid_receiver,
mojom::BindInterfacePriority priority,
mojom::Connector::BindInterfaceCallback callback);
// Variant of the above when no Service remote or PIDReceiver is provided by
// the caller.
void Connect(const ServiceFilter& partial_target_filter,
const Identity& source_identity,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojom::BindInterfacePriority priority,
mojom::Connector::BindInterfaceCallback callback);
// Variant of the above where no interface name, receiving pipe, Service
// remote, or PIDReceiver is provided by the caller.
void Connect(const ServiceFilter& partial_target_filter,
const Identity& source_identity,
mojom::Connector::BindInterfaceCallback callback);
// Variant of the above where no interface name or receiving pipe is provided
// by the caller, but a Service remote and PIDReceiver are provided.
void Connect(const ServiceFilter& partial_target_filter,
const Identity& source_identity,
mojo::PendingRemote<mojom::Service> service_remote,
mojo::PendingReceiver<mojom::PIDReceiver> pid_receiver,
mojom::Connector::BindInterfaceCallback callback);
// Attempts to locate a ServiceInstance as a target for a connection request
// from |source_instance| by matching against |partial_target_filter|. If
// a suitable instance exists it is returned, otherwise the Service Manager
// attempts to create a new suitable instance.
//
// Returns null if a matching instance did not exist and could not be created,
// otherwise returns a valid ServiceInstance which matches
// |partial_target_filter| from |source_instance|'s perspective.
ServiceInstance* FindOrCreateMatchingTargetInstance(
const ServiceInstance& source_instance,
const ServiceFilter& partial_target_filter);
private:
friend class ServiceInstance;
......@@ -129,7 +108,7 @@ class ServiceManager : public Service {
// Returns a running instance identified by |identity|.
ServiceInstance* GetExistingInstance(const Identity& identity) const;
void NotifyServiceCreated(ServiceInstance* instance);
void NotifyServiceCreated(const ServiceInstance& instance);
void NotifyServiceStarted(const Identity& identity, base::ProcessId pid);
void NotifyServiceFailedToStart(const Identity& identity);
......@@ -141,11 +120,6 @@ class ServiceManager : public Service {
// Called from the instance implementing mojom::ServiceManager.
void AddListener(mojom::ServiceManagerListenerPtr listener);
void CreateServiceWithFactory(const ServiceFilter& service_factory_filter,
const std::string& name,
mojom::ServiceRequest request,
mojom::PIDReceiverPtr pid_receiver);
// Returns a running ServiceFactory for |filter|. If there is not one running,
// one is started.
mojom::ServiceFactory* GetServiceFactory(const ServiceFilter& filter);
......
......@@ -558,15 +558,16 @@ TEST_F(ConnectTest, MAYBE_PackagedApp_BlockedInterface) {
// Connection to another application provided by the same package, blocked
// because it's not in the capability filter whitelist.
TEST_F(ConnectTest, MAYBE_BlockedPackagedApplication) {
mojom::ConnectResult result;
base::RunLoop run_loop;
test::mojom::ConnectTestServicePtr service_b;
connector()->BindInterface(
ServiceFilter::ByName(kTestAppBName), mojo::MakeRequest(&service_b),
base::BindOnce(&StartServiceResponse, nullptr, &result, nullptr));
service_b.set_connection_error_handler(run_loop.QuitClosure());
run_loop.Run();
base::BindLambdaForTesting([&](mojom::ConnectResult result,
const base::Optional<Identity>& identity) {
EXPECT_EQ(mojom::ConnectResult::ACCESS_DENIED, result);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(ConnectTest, CapabilityClasses) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment