| # 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 `/garnet/bin/setui:setui_service` 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 += [ |
| "//garnet/bin/setui:setui_service", |
| ] |
| ``` |
| |
| The service is associated with Settings through [sysmgr][sysmgr], which maps the |
| protocols to the service. Since the service's dependencies are downstream from |
| other system components, Settings is an optional and need not be included on |
| products that don't utilize it. |
| |
| 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: |
| |
| - {cml} |
| |
| ```json5 |
| { |
| program: { |
| runner: "elf", |
| binary: "bin/example", |
| }, |
| use: [ |
| { protocol: "fuchsia.settings.Accessibility" }, |
| ], |
| } |
| ``` |
| |
| - {cmx} |
| |
| ```json |
| { |
| "program": { |
| "binary": "bin/example" |
| }, |
| "sandbox": { |
| "services": [ |
| "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; |
| }) -> (struct {}) 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::EMPTY; |
| new_settings.screen_reader = Some(true); |
| proxy.set(new_settings).await.expect("request completed").expect("request succeeded"); |
| ``` |
| |
| ## Debugging |
| |
| Settings offers a command-line utility for interacting with its protocols, called |
| SetUI Client. This tool gives developers real-time access to Settings, enabling |
| them to see how their application affects and is affected by Settings. SetUI |
| Client can be included in a build by specifying its package in the build |
| environment: |
| |
| ```posix-terminal |
| fx set core.x64 --with //garnet/packages/prod:setui_client |
| ``` |
| |
| Since the utility is not part of the base packages, it is important to have the |
| package server [serving][pkg] at execution time. A Setting protocol's current |
| information can be retrieved by calling SetUI client with the protocol's name as |
| an argument. For example, the following command retrieves information about |
| Accessibility: |
| |
| ```posix-terminal |
| fx shell run fuchsia-pkg://fuchsia.com/setui_client#meta/setui_client.cmx accessibility |
| ``` |
| |
| SetUI Client can also modify Settings. The utility's help command details the |
| specific modification syntax per protocol: |
| |
| ```posix-terminal |
| fx shell run fuchsia-pkg://fuchsia.com/setui_client#meta/setui_client.cmx accessibility help |
| ``` |
| |
| Finishing the example, the SetUI Client can be done as follows: |
| |
| ```posix-terminal |
| fx shell run fuchsia-pkg://fuchsia.com/setui_client#meta/setui_client.cmx accessibility -s true |
| ``` |
| |
| <!-- link labels --> |
| [sdk]: /sdk/fidl/fuchsia.settings/ |
| [fidl]: /docs/concepts/fidl/overview.md |
| [build]: /docs/concepts/build_system/fuchsia_build_system_overview.md |
| [sysmgr]: /src/sys/sysmgr/README.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 |
| [pkg]: /docs/development/build/fx.md#serve-a-build |