Service capabilities

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

Providing service capabilities

Components provide service capabilities by either:

Components host service capabilities in their outgoing directory.

Exposing

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

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

The "from": "self" directive means that the service capability was created by this component.

Offering

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

{
    "offer": [{
        "service": "/svc/fuchsia.example.ExampleService",
        "from": "self",
        "to": [{
            { "dest": "#child-a" },
            { "dest": "#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": "/svc/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.

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

For a working example of routing a service capability from one component to another, see //examples/components/routing.

Service paths

When a service capability is used by a component, its path refers to the path in the component's [namespace][namespace].

When a service capability is offered or exposed from itself, its path refers to the path in the component's [outgoing directory][outgoing].

The path also hints to clients which FIDL service the server expects clients to use, but this is entirely a convention. Service capability paths can be renamed when being offered, exposed, or used.

In the following example, there are three components, A, B, and C, with the following layout:

 A  <- offers service "/svc/fidl.example.X" from self to B as "/intermediary"
 |
 B  <- offers service "/intermediary" from realm to B as "/intermediary2"
 |
 C  <- uses service "/intermediary2" as "/service/example"

Each component in this example changes the path used to reference the service when passing it along in this chain, and so long as components A and C know which FIDL service to use over the channel, this will work just fine.

A.cml:
{
    "offer": [{
        "service": "/svc/fidl.example.X",
        "from": "self",
        "to": [{
            { "dest": "#B", "as": "/intermediary" },
        }],
    }],
    "children": [{
        "name": "B",
        "url": "fuchsia-pkg://fuchsia.com/B#B.cm",
    }],
}
B.cml:
{
    "offer": [{
        "service": "/intermediary",
        "from": "realm",
        "to": [{
            { "dest": "#C", "as": "/intermediary2" },
        }],
    }],
    "children": [{
        "name": "C",
        "url": "fuchsia-pkg://fuchsia.com/C#C.cm",
    }],
}
C.cml:
{
    "use": [{
        "service": "/intermediary2",
        "as": "/service/example",
    }],
}

When C attempts to open the example node in its /service directory, A sees an open request for /svc/fidl.example.X. If any of the names don't match in this chain, C will see its open attempt fail.