Configuration capabilities allow components to define, route, and use configuration values. A component that uses a configuration capability will see that value appear in its structured configuration.
Defining configuration capabilities
To define a configuration capability, a component must add a capabilities
declaration
for it:
{
capabilities: [
{
config: "fuchsia.config.MyBool",
type: "bool",
value: true,
},
],
}
This defines the capability fuchsia.config.MyBool
of type bool
with the value of true
.
Please see the capabilities reference for more information
on the supported fields for type
and value
.
Routing configuration capabilities
Components route configuration capabilities by exposing them to their parent or offering them to their children.
For more details on how the framework routes component capabilities, see capability routing.
Exposing
Exposing a configuration capability gives the component's parent access to that capability:
{
expose: [
{
config: "fuchsia.config.MyBool",
from: "self",
},
],
}
You may optionally specify:
Offering
Offering a configuration capability gives a child component access to that capability:
{
offer: [
{
config: "fuchsia.config.MyBool",
from: "parent",
to: [ "#child-a", "#child-b" ],
},
],
}
You may optionally specify:
Using configuration capabilities
To use a configuration capability, the component must add a use
definition that links the
capability to a structured configuration value. Then, the component will be able to read its
structured configuration at runtime to see the value of the capability.
Consider a component with the following structured configuration block:
json5
{
config: {
say_hello: { type: "bool" },
},
}
To use a configuration capability, add a use
declaration for it:
{
use: [
{
config: "fuchsia.config.MyBool",
key: "say_hello",
from: "parent",
},
],
}
When a component reads the say_hello
field of its structured configuration, it will be
receiving the value of fuchsia.config.MyBool
.
You may optionally specify:
Renaming
You may expose
or offer
a capability by a different name:
{
offer: [
{
config: "fuchsia.config.MyBool",
from: "#child-a",
to: [ "#child-b" ],
as: "fuchsia.childB.SayHello",
},
],
}
Configuration types
There are many supported types for configuration values.
There are the following types for unsigned integers:
uint8
uint16
uint32
uint64
There are the following types for signed integers:
int8
int16
int32
int64
There is the bool
type which supports values of true
or false
.
There is the string
type, which must have max_size
set in addition to the string value.
String example:
{
capabilities: [
{
config: "fuchsia.config.MyString",
type: "string",
max_size: 100,
value: "test",
},
]
}
There is the vector
type, which must have a element
field with type
also set. Vectors can
contain all other types except for vectors.
Vector example:
{
capabilities: [
{
config: "fuchsia.config.MyUint8Vector",
type: "vector",
element: { type: "uint8" },
max_count: 100,
value: [1, 2, 3 ],
},
{
config: "fuchsia.config.MyStringVector",
type: "vector",
element: {
type: "string",
max_size: 100,
},
max_count: 100,
value: [
"Hello",
"World!",
],
},
],
}
Optional routing
Use
, Offer
, and Expose
for configuration capabilities support availability. This means that
a component can optionally
use a configuration capability. For more information, please see
consuming optional capabilities
Default values
If a config capability is routed optionally, then a route from void
means that
it will be given a default value. It is an error to specify an optional
configuration capability without providing a default value.
There are two ways to specify a default value.
Defining the default value in the CML file
The simplest way to define a default value is to specify it in CML with the
default
keyword.
For example:
{
use: {
config: "fuchsia.config.MyInt",
key: "my_int",
type: "int8",
availability: "optional",
default: 42,
}
}
The fuchsia.config.MyInt
will receive a default value of 42
if it is routed
from void
.
The CML file default value will always be taken over the Structured Configuration default value defined in the next section.
(Legacy) Structured Configuration as a default value
A legacy way to define a default value is to include it in the component's package as structured configuration.
For example:
{
use: {
config: "fuchsia.config.MyInt",
key: "my_int",
type: "int8",
availability: "optional",
}
config: {
my_int: {
type: "int8"
},
}
}
In the above example, fuchsia.config.MyInt
is being used as my_int
which
matches a configuration value in the config
block. The developer can then use
existing structured configuration tools to create a
configuration file in the component's package that will be used as the default
value.
Note that this approach is always overriden by specifying default:
directly in
the CML file.
Resolving routes and broken routes
Structured configuration values are handed to a component when it starts up. This means that the Component Framework must resolve all of the routes for configuration capabilities before the component is started.
A side effect of this means that the Component Framework is unable to start a
component that has a "broken route" (a route that does not successfully end in a
capability definition) for a configuration capability. For example, if you
request fuchsia.config.MyBool
but your parent does not offer it to you, you
will not be able to start. This is different than other capabilities, where the
component will discover at runtime that it may not exist.
Updating configuration values
Because configuration values are handed to a component when it starts, the component will not see any updates if the capability route changes while the component is running.
In order to launch a component with a different configuration the following things need to happen:
- Either:
- Update the CML providing the configuration capability (likely by re-resolving it).
- Use the
ffx component config
tool to update the configuration values from the command line.
- Stop and then Start the component that is using the configuration capability.