Protocol capabilities

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

Providing protocol capabilities

Components provide protocol capabilities by either:

Components host protocol capabilities in their outgoing directory.

Exposing

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

{
    "expose": [{
        "protocol": "/svc/fuchsia.example.ExampleProtocol",
        "from": "self",
    }],
}

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

Offering

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

{
    "offer": [{
        "protocol": "/svc/fuchsia.example.ExampleProtocol",
        "from": "self",
        "to": [{
            { "dest": "#child-a" },
            { "dest": "#child-b" },
        }],
    }],
}

Consuming protocol capabilities

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

Consider a component with the following manifest declaration:

{
    "use": [{
        "protocol": "/svc/fuchsia.example.ExampleProtocol",
    }],
}

When the component attempts to open the path /svc/fuchsia.example.ExampleProtocol, the component framework performs capability routing to find the component that provides this protocol. 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 protocol capability from one component to another, see //examples/components/routing.

Consuming protocol capabilities provided by the framework

Some protocol capabilities are provided by the component framework, and thus can be used by components without their parents offering them.

For a list of these protocols and what they can be used for, see framework protocols.

{
    "use": [{
        "protocol": "/svc/fuchsia.sys2.Realm",
        "from": "framework",
    }],
}

Protocol paths

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

When a protocol 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 protocol the server expects clients to use, but this is entirely a convention. Protocol 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 protocol "/svc/fidl.example.X" from self to B as "/intermediary"
 |
 B  <- offers protocol "/intermediary" from realm to B as "/intermediary2"
 |
 C  <- uses protocol "/intermediary2" as "/protocol/example"

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

A.cml:
{
    "offer": [{
        "protocol": "/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": [{
        "protocol": "/intermediary",
        "from": "realm",
        "to": [{
            { "dest": "#C", "as": "/intermediary2" },
        }],
    }],
    "children": [{
        "name": "C",
        "url": "fuchsia-pkg://fuchsia.com/C#C.cm",
    }],
}
C.cml:
{
    "use": [{
        "protocol": "/intermediary2",
        "as": "/svc/example",
    }],
}

When C attempts to open the example node in its /protocol 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.