#include "services/service_manager/public/cpp/service_receiver.h"
#include <utility>
#include "base/functional/bind.h"
#include "base/synchronization/lock.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/service_manager/public/cpp/service.h"
namespace service_manager {
ServiceReceiver::ServiceReceiver(service_manager::Service* service)
: service_(service) {
DCHECK(service_);
}
ServiceReceiver::ServiceReceiver(service_manager::Service* service,
mojo::PendingReceiver<mojom::Service> receiver)
: ServiceReceiver(service) {
if (receiver.is_valid())
Bind(std::move(receiver));
}
ServiceReceiver::~ServiceReceiver() = default;
Connector* ServiceReceiver::GetConnector() {
if (!connector_)
connector_ = Connector::Create(&pending_connector_receiver_);
return connector_.get();
}
void ServiceReceiver::Bind(mojo::PendingReceiver<mojom::Service> receiver) {
DCHECK(!is_bound());
receiver_.Bind(std::move(receiver));
receiver_.set_disconnect_handler(base::BindOnce(
&ServiceReceiver::OnConnectionError, base::Unretained(this)));
}
void ServiceReceiver::RequestClose() {
if (!is_bound())
return;
if (service_control_.is_bound()) {
service_control_->RequestQuit();
} else {
request_closure_on_start_ = true;
}
}
void ServiceReceiver::Close() {
DCHECK(is_bound());
receiver_.reset();
service_control_.reset();
connector_.reset();
}
void ServiceReceiver::OnConnectionError() {
service_->OnDisconnected();
}
void ServiceReceiver::OnStart(const Identity& identity,
OnStartCallback callback) {
identity_ = identity;
if (!pending_connector_receiver_.is_valid())
connector_ = Connector::Create(&pending_connector_receiver_);
std::move(callback).Run(std::move(pending_connector_receiver_),
service_control_.BindNewEndpointAndPassReceiver());
service_->OnStart();
if (request_closure_on_start_)
service_control_->RequestQuit();
}
void ServiceReceiver::OnBindInterface(
const BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe,
OnBindInterfaceCallback callback) {
std::move(callback).Run();
service_->OnConnect(source_info, interface_name, std::move(interface_pipe));
}
void ServiceReceiver::CreatePackagedServiceInstance(
const Identity& identity,
mojo::PendingReceiver<mojom::Service> receiver,
mojo::PendingRemote<mojom::ProcessMetadata> metadata) {
service_->CreatePackagedServiceInstance(
identity.name(), std::move(receiver),
base::BindOnce(
[](mojo::PendingRemote<mojom::ProcessMetadata> pending_metadata,
absl::optional<base::ProcessId> pid) {
if (pid) {
mojo::Remote<mojom::ProcessMetadata> metadata(
std::move(pending_metadata));
metadata->SetPID(*pid);
}
},
std::move(metadata)));
}
}