# 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
