| # ChromeOS Feature Daemon |
| |
| `featured` is a service used for enabling and managing platform specific |
| features. Its main user is Chrome field trials. |
| |
| ## Components |
| |
| In this directory are two main components: `feature_library` and featured. |
| |
| ### feature\_library |
| |
| The `feature_library` is the main way most users will interact with variations |
| in platform2. (If you're familiar with |
| [base::Feature and base::FeatureList](https://source.chromium.org/chromium/chromium/src/+/main:base/feature_list.h) |
| in chrome, it will look very similar.) Most documentation for this is in |
| `feature_library.h`, but there is also a C wrapper API as well as a Rust API. |
| |
| As of March 2023, all features queried via `feature_library` must start with |
| CrOSLateBoot. For CrOSLateBoot features, `feature_library` is a thin wrapper |
| around a dbus call to ash-chrome, so state can only be queried **after** chrome |
| is up. |
| |
| Work is underway to support "early boot" features as well; feel free to contact |
| OWNERS for more details. |
| |
| #### Using feature\_library |
| Clients can use `feature_library` by creating an instance of |
| [PlatformFeatures](https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform2/featured/feature_library.h;l=169). |
| The instance is used to query feature state and associated parameters, if there are any. |
| |
| `PlatformFeatures` is implemented as a singleton class and is thread-safe. |
| Here is an example of how to initialize and obtain an instance: |
| |
| ``` |
| dbus::Bus::Options options; |
| options.bus_type = dbus::Bus::SYSTEM; |
| scoped_refptr<dbus::Bus> bus(new dbus::Bus(options)); |
| |
| // |Initialize| must be called before calling |Get| and the return value must |
| // be used since it has the [[nodiscard]] attribute. |
| CHECK(feature::PlatformFeatures::Initialize(bus)); |
| |
| // |Get| will return a valid handle if |Initialize| succeeds. |
| // Note that |Get| and subsequent calls can happen much later than |Initialize| |
| // since the object pointer remains valid until program exit. |
| feature::PlatformFeatures* feature_lib = feature::PlatformFeatures::Get(); |
| |
| // Use the handle to query feature state. |
| feature_lib->GetParamsAndEnabled(...); |
| ``` |
| |
| Note that no shutdown call is necessary. The initialized instance will get |
| automatically cleaned up on program exit. |
| |
| [platform2/featured/cpp_feature_check_example.cc](https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform2/featured/cpp_feature_check_example.cc) |
| provides another example on how to use `PlatformFeatures` and associated |
| functions like `IsEnabled{,Blocking}`, and `GetParamsAndEnabled{,Blocking}`. |
| |
| ### featured |
| |
| The feature daemon (featured) is primarily responsible for managing |
| [share/platform-features.json](https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform2/featured/share/platform-features.json). |
| This file configures platform and kernel features that can be enabled |
| _dynamically_ at runtime, late in boot (that is, after user login). |
| |
| Each entry in this file consists of a feature name, to be checked using |
| `feature_library`, an optional set of `support_check_commands` (to check whether |
| the device supports the feature), and a set of `commands` to be run when the |
| feature is supported and chrome determines that it should be enabled. |
| |
| Support check commands include FileExists and FileNotExists. Commands to execute |
| include WriteFile and Mkdir, which respectively write specified contents to a |
| file and create a given directory. |
| |
| Featured is heavily sandboxed: writing to a new location requires an update to |
| selinux policy in `platform2/sepolicy/policy/chromeos/cros_featured.te` as well |
| as the allow-list in service.cc (see `CheckPathPrefix`). |
| |
| We are actively working (in 2023) on support for "early boot" features in |
| featured. The primary user interface for these will be via `feature_library`, |
| but featured will perform some work to support this, largely behind the scenes. |
| |
| ### Upstart Configurations |
| |
| Featured starts relatively late in boot, during |
| [system-services](https://www.chromium.org/chromium-os/chromiumos-design-docs/boot-design/#system-services-startup), |
| since Chrome needs to be available for platform-features.json support to work. |
| |
| Additionally, featured waits for user login to enable platform-features.json |
| features for two reasons: |
| 1. **Safety:** It is easier to roll back after user login since it is more |
| likely for the platform to have connected to the network and downloaded a new |
| seed. |
| 2. **Compatibility:** Historically, we have checked after login. There is no |
| strong reason to change that, and changing it could break existing users. |
| |
| Upon crashes or abnormal exits (non-zero status code), featured restarts with |
| the intention that if we fail initially, we want to re-try and make sure |
| platform-features.json (and eventually "early boot" features) will work. |
| |
| We are actively working (in 2023) on support for "early boot" features in |
| featured. To support "early boot" features, featured startup will be moved |
| earlier to start during |
| [basic services](https://www.chromium.org/chromium-os/chromiumos-design-docs/boot-design/#basic-services-startup). |