Service capabilities

<<../../_v2_banner.md>>

Service capabilities allow components to connect to FIDL services provided either by other components or the component framework itself.

Note: Protocol and service capabilities are distinct types of capabilities. A protocol represents a single instance of a FIDL protocol, while a service represents zero or more instances of a FIDL service. See the documentation on protocol capabilities for more details.

Providing service capabilities

To provide a service capability, a component must define the capability and route it from self. The component hosts the service capability in its outgoing directory.

To define the capability, add a capabilities declaration for it:

{
    capabilities: [
        {
            service: "fuchsia.example.ExampleService",
        },
    ],
}

This defines a capability hosted by this component whose outgoing directory path is /svc/fuchsia.example.ExampleService. You can also customize the path:

{
    capabilities: [
        {
            service: "fuchsia.example.ExampleService",
            path: "/my_svc/fuchsia.example.MyExampleService",
        },
    ],
}

Routing service capabilities

Components route service capabilities by exposing them to their parent and offering them to their children.

Exposing

Exposing a service capability gives the component's parent access to that capability. This is done through an expose declaration.

{
    expose: [
        {
            service: "fuchsia.example.ExampleService",
            from: "self",
        },
    ],
}

The from: "self" directive means that the service capability is provided by this component. In this case the service must have a corresponding definition.

Services routed from collections

A service capability can be exposed from a dynamic collection.

{
    collections: [
        {
            name: "coll",
            durability: "transient",
        },
    ],
    expose: [
        {
            service: "fuchsia.example.ExampleService",
            from: "#coll",
        },
    ],
}

When routing services exposed from the components in a collection, each service instance entry in the client component's namespace is prefixed with the component name to allow multiple components in the collection to expose the same instance.

The instances are named with the scheme "$component_name,$instance_name". The $component_name is the name given to the fuchsia.sys2/Realm.CreateChild API when the component is created. The $instance_name is defined by the component itself.

For example, the namespace path for the default instance of fuchsia.example.ExampleService exposed from a component named foo within the above collection is /svc/fuchsia.example.ExampleService/foo,default/protocol.

Offering

Offering a service capability gives a child component access to that capability. This is done through an offer declaration.

{
    offer: [
        {
            service: "fuchsia.example.ExampleService",
            from: "self",
            to: [ "#child-a", "#child_b" ],
        },
    ],
}

Consuming service capabilities

When a component uses a service capability that has been offered to it, that service is made available through the component's namespace.

Consider a component with the following manifest declaration:

{
    use: [
        {
            service: "fuchsia.example.ExampleService",
        },
    ],
}

When the component attempts to open the path /svc/fuchsia.example.ExampleService, the component framework performs capability routing to find the component that provides this service. Then, the framework connects the newly opened channel to this provider.

You can also customize the namespace path:

{
    use: [
        {
            service: "fuchsia.example.ExampleService",
            path: "/my_svc/fuchsia.example.MyExampleService",
        },
    ],
}

For more information about the open request, see life of a protocol open.

Note: For a working example of routing a service capability between components, see //examples/components/services.