| # 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 |