blob: cd7b6c1983c7776fd4b6fa7f968707ba5b67ae31 [file] [log] [blame] [view]
# Using Settings
Settings is part of the [Fuchsia SDK][sdk] and is available on products with the
proper supporting packages. Applications on these products can interact with
Settings if they have the appropriate permissions. The interaction follows a
common pattern for accessing and modifying settings across the Settings
protocols.
This guide walks through the steps for incorporating Settings into an
application and interacting with Settings.
## Prerequisites
The Setting Service supports the Settings protocols in Fuchsia. The service's
package `//src/settings/service:setui_service` and one of its core shard
such as `//src/settings/service:setui_service_core_shard` must be present in the
product definition in order to use Settings. The following product definition
includes Settings:
```gn
import("//products/bringup.gni")
base_package_labels += [
"//src/settings/service:setui_service",
]
core_realm_shards += [
"//src/settings/service:setui_service_core_shard",
]
```
For more information about Fuchsia's build system, see [The Fuchsia build
system][build].
### Permissions
Any application that accesses Settings must declare usage through its component
manifest. For example, the following manifest declares access to the
[fuchsia.settings.accessibility][accessibility] protocol:
```json5
{
program: {
runner: "elf",
binary: "bin/example",
},
use: [
{ protocol: "fuchsia.settings.Accessibility" },
],
}
```
For more information about Fuchsia components, see
[Component manifests][manifest].
## Connecting
Applications access Settings through the runtime bindings found in the Fuchsia
SDK. This guide will use Rust for examples, but bindings are available for a
variety of other languages, such as C++ and Dart.
Like other [FIDL][fidl] protocols, the first step to accessing Settings is to
connect to the Setting Service. The following example connects to
[fuchsia.settings.accessibility][accessibility]:
```rust
let proxy = connect_to_protocol::<AccessibilityMarker>().context("failed to connect to Settings");
```
In the above example, `connect_to_protocol` and `AccessibilityMarker` are
provided through the SDK.
Clients should communicate with each Setting protocol over a single connection.
Ongoing communication must occur over the same connection to ensure
the consistency and continuity of responses, as explored in later sections.
## Reading
Each Setting protocol defines a [table][fidl_table] for conveying relevant
details, such as state and status. Organizing data under a single structure
allows Settings to succinctly convey information. The structure also facilitates
communicating changes, as discussed [later](#writing). In the Accessibility
example, `AccessibilitySettings` captures relevant details:
<a name="a11y-table"></a>
```fidl
/// Supported accessibility settings.
type AccessibilitySettings = table {
/// For videos, use an alternative audio track (akin to changing languages)
/// that explains what is happening visually while there is no dialogue.
1: audio_description bool;
/// Read aloud elements of the screen selected by the user.
2: screen_reader bool;
/// Invert colors on the screen.
3: color_inversion bool;
/// Interpret triple-tap on the touchscreen as a command to zoom in.
4: enable_magnification bool;
/// What type of color-blindness, if any, to correct for.
5: color_correction ColorBlindnessType;
/// What kind of sources get closed captions, and how they look.
6: captions_settings CaptionsSettings;
};
```
A method, called Watch, is present in each protocol to provide access to this
information. This is the declaration for
[fuchsia.settings.accessibility][accessibility]:
```fidl
Watch() -> (struct {
settings AccessibilitySettings;
});
```
`Watch` follows the [hanging get pattern][hanging-get], returning the current
information on the initial call. Responses to subsequent invocations are
deferred until there is an update to the last returned value. Using the same
proxy connection across these requests is critical for this behavior as Settings
tracks the delivered responses based on the channel. If an error occurs,
Settings will close the FIDL channel with a relevant [epitaph][epitaph].
In the Accessibility example, call `Watch` to determine if the screen reader is
enabled:
```rust
let settings = proxy.watch().expect("settings retrieved");
let screen_reader_enabled = settings.screen_reader.ok_or(false);
```
## Writing
Applications can affect Settings by utilizing the same table structure found
for reading data. Each mutable protocol offers a counterpart method to `Watch`
called `Set`, which takes [AccessibilitySettings](#a11y-table) as an argument:
```fidl
Set(struct {
settings AccessibilitySettings;
}) -> () error Error;
```
Changes are conveyed by specifying the desired final state in the table fields.
Since each field is optional, only affected fields need to be specified.
By defining changes as deltas, race conditions from multiple callers are
avoided. If successful, the change will be persisted and applied across boots.
Continuing the previous example, a caller can enable the screen reader with the
following code:
```rust
let new_settings = AccessibilitySettings::default();
new_settings.screen_reader = Some(true);
proxy.set(new_settings).await.expect("request completed").expect("request succeeded");
```
## Debugging
Settings offers a Fuchsia CLI tool ([`ffx setui`][ffx-setui]) for interacting
with its protocols. This tool gives developers real-time access to Settings,
enabling them to see how their application affects and is affected by Settings.
The `ffx setui` tool comes with the Fuchsia source code and SDK. To use it, run
the following command first to opt in:
```posix-terminal
ffx config set setui true
```
To retrieve a Setting protocol's current information (except Accessibility and
VolumePolicy), you can call `ffx setui` with the protocol's name as an argument.
For example, the following command retrieves information about Privacy:
```posix-terminal
ffx setui privacy
```
For Accessibility, add the keyword `watch` after the protocol's name:
```
ffx setui accessibility watch
```
For VolumePolicy, add the keyword `get` after the protocol's name:
```
ffx setui volume_policy get
```
`ffx setui` can also modify Settings. The utility's `help` command details the
specific modification syntax per protocol:
```posix-terminal
ffx setui privacy help
```
Here is an example of setting the user data sharing consent
(`user-data-sharing-consent`) to true:
```posix-terminal
ffx setui privacy -u true
```
<!-- link labels -->
[sdk]: /sdk/fidl/fuchsia.settings/
[fidl]: /docs/concepts/fidl/overview.md
[build]: /docs/development/build/build_system/fuchsia_build_system_overview.md
[accessibility]: /sdk/fidl/fuchsia.settings/accessibility.fidl
[manifest]: /docs/concepts/components/v2/component_manifests.md
[hanging-get]: /docs/development/api/fidl.md#hanging-get
[fidl_table]: /docs/reference/fidl/language/language.md#tables
[epitaph]: /docs/contribute/governance/rfcs/0053_epitaphs.md
[ffx-setui]: https://fuchsia.dev/reference/tools/sdk/ffx#setui