#ifndef SERVICES_SERVICE_MANAGER_SERVICE_INSTANCE_H_
#define SERVICES_SERVICE_MANAGER_SERVICE_INSTANCE_H_
#include <stdint.h>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process_handle.h"
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/service_manager/public/cpp/identity.h"
#include "services/service_manager/public/cpp/manifest.h"
#include "services/service_manager/public/mojom/connector.mojom.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#include "services/service_manager/public/mojom/service_control.mojom.h"
#include "services/service_manager/public/mojom/service_manager.mojom.h"
namespace sandbox {
namespace mojom {
enum class Sandbox;
}
}
namespace service_manager {
class ServiceManager;
class ServiceProcessHost;
class ServiceInstance : public mojom::Connector,
public mojom::ProcessMetadata,
public mojom::ServiceControl,
public mojom::ServiceManager {
public:
ServiceInstance(service_manager::ServiceManager* service_manager,
const Identity& identity,
const Manifest& manifest);
ServiceInstance(const ServiceInstance&) = delete;
ServiceInstance& operator=(const ServiceInstance&) = delete;
~ServiceInstance() override;
const Identity& identity() const { return identity_; }
const Manifest& manifest() const { return manifest_; }
void SetPID(base::ProcessId pid) override;
void StartWithRemote(mojo::PendingRemote<mojom::Service> remote);
#if !BUILDFLAG(IS_IOS)
bool StartWithProcessHost(std::unique_ptr<ServiceProcessHost> host,
sandbox::mojom::Sandbox sandbox_type);
#endif
void BindProcessMetadataReceiver(
mojo::PendingReceiver<mojom::ProcessMetadata> receiver);
bool MaybeAcceptConnectionRequest(
const ServiceInstance& source_instance,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojom::BindInterfacePriority priority);
bool CreatePackagedServiceInstance(
const Identity& packaged_instance_identity,
mojo::PendingReceiver<mojom::Service> receiver,
mojo::PendingRemote<mojom::ProcessMetadata> metadata);
void Stop();
mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const;
void BindServiceManagerReceiver(
mojo::PendingReceiver<mojom::ServiceManager> receiver);
private:
class InterfaceFilter;
friend class InterfaceFilter;
void OnStartCompleted(
mojo::PendingReceiver<mojom::Connector> connector_receiver,
mojo::PendingAssociatedReceiver<mojom::ServiceControl> control_receiver);
void OnConnectRequestAcknowledged();
void MarkUnreachable();
void MaybeNotifyPidAvailable();
void OnServiceDisconnected();
void OnConnectorDisconnected();
void HandleServiceOrConnectorDisconnection();
bool CanConnectToOtherInstance(
const ServiceFilter& target_filter,
const std::optional<std::string>& target_interface_name);
void BindInterface(const ServiceFilter& target_filter,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe,
mojom::BindInterfacePriority priority,
BindInterfaceCallback callback) override;
void QueryService(const std::string& service_name,
QueryServiceCallback callback) override;
void WarmService(const ServiceFilter& target_filter,
WarmServiceCallback callback) override;
void RegisterServiceInstance(
const Identity& identity,
mojo::ScopedMessagePipeHandle service_remote_handle,
mojo::PendingReceiver<mojom::ProcessMetadata> metadata_receiver,
RegisterServiceInstanceCallback callback) override;
void Clone(mojo::PendingReceiver<mojom::Connector> receiver) override;
void RequestQuit() override;
void AddListener(
mojo::PendingRemote<mojom::ServiceManagerListener> listener) override;
const raw_ptr<service_manager::ServiceManager> service_manager_;
const Identity identity_;
const Manifest manifest_;
const bool can_contact_all_services_;
#if !BUILDFLAG(IS_IOS)
std::unique_ptr<ServiceProcessHost> process_host_;
#endif
mojo::Remote<mojom::Service> service_remote_;
mojo::Receiver<mojom::ProcessMetadata> process_metadata_receiver_{this};
mojo::ReceiverSet<mojom::Connector> connector_receivers_;
mojo::ReceiverSet<mojom::ServiceManager> service_manager_receivers_;
mojo::AssociatedReceiver<mojom::ServiceControl> control_receiver_{this};
base::ProcessId pid_ = base::kNullProcessId;
mojom::InstanceState state_ = mojom::InstanceState::kCreated;
bool stopped_ = false;
int pending_service_connections_ = 0;
base::WeakPtrFactory<ServiceInstance> weak_ptr_factory_{this};
};
}
#endif