// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.settings;

using fuchsia.ui.types;

/// Settings related to display.
///
/// Supported SettingsEpitaph enums:
/// REQUEST_NOT_SUPPORTED, INTERNAL_SERVICE_ERROR, PERSISTENT_STORAGE_ERROR
@discoverable(server="platform")
closed protocol Display {
    /// Gets the current [DisplaySettings]. Returns immediately on first call;
    /// subsequent calls return when the value changes.
    ///
    /// If this call fails, it is considered a fatal error and the channel
    /// will be closed.
    strict Watch() -> (struct {
        settings DisplaySettings;
    });

    /// Obtains the current data from the light sensor. Returns immediately on
    /// first call; subsequent calls return when the light sensor value changes
    ///  by a certain amount measured in lux.
    ///
    /// If this call fails, it is considered a fatal error and the channel
    /// will be closed.
    @available(deprecated=10, removed=16, note="Use fuchsia.lightsensor.Sensor::Watch")
    strict WatchLightSensor(struct {
        delta float32;
    }) -> (struct {
        light_sensor_data LightSensorData;
    });

    /// Sets display settings. Any field not explicitly set in the table performs a
    /// no-op, and will not make any changes.
    strict Set(struct {
        settings DisplaySettings;
    }) -> () error Error;
};

/// DisplaySettings are used to determine the output state of the display.
/// The display can be toggled between two modes, auto-brightness on and
/// auto-brightness off.
///
/// Adjusted_auto_brightness is used to set a specific brightness level for the
/// current lighting conditions. Auto-brightness will continue to make the
/// screen darker and brighter as the surrounding light changes.
///
/// Brightness_value is used in manual mode to set a specific brightness level
/// for the screen. This level will be maintained while in manual mode.
type DisplaySettings = table {
    /// Auto brightness enabled.
    1: auto_brightness bool;
    /// Manually set brightness value [0.0 - 1.0]. Not a number, infinity or
    /// negative infinity will cause SetDisplayInfo to fail with INVALID_VALUE.
    2: brightness_value float32;
    /// The low light mode state of the device.
    4: low_light_mode LowLightMode;
    /// Whether the screen is enabled.
    5: screen_enabled bool;
    /// Theme to be used for the device's user interface.
    6: theme Theme;
    /// Brightness value to adjust auto-brightness to [0.0 - 1.0].
    7: adjusted_auto_brightness float32;
};

/// # Deprecation
///
/// This struct is being replaced with the struct
/// fuchsia.lightsensor.LightSensorData. The [illuminance_lux] value here was
/// incorrectly named and actually represents the clear color channel from the
/// light sensor.
@available(deprecated=10, removed=16, note="Use fuchsia.lightsensor.LightSensorData")
type LightSensorData = table {
    /// Brightness from the light sensor (a.k.a. the `Clear` value in RGBC).
    1: illuminance_lux float32;

    /// Color measured by light sensor in rgb.
    2: color fuchsia.ui.types.ColorRgb;
};

type Theme = table {
    // theme_type will be absent if no theme has been set.
    1: theme_type ThemeType;
    // Lack of a theme mode can be represented by an absent theme_mode or a
    // theme_mode of 0x0.
    2: theme_mode ThemeMode;
};

@strict_audit(bug="https://fxbug.dev/467128325", state="PENDING_REVIEW")
type LowLightMode = strict enum {
    /// Device should not be in low-light mode.
    DISABLE = 0;
    /// Device should not be in low-light mode and should transition
    /// out of it immediately.
    DISABLE_IMMEDIATELY = 1;
    /// Device should be in low-light mode.
    ENABLE = 2;
};

// Specifies a specific theme that should be used by the UI.
// Any other theme information, such as guidance as to how to pick a theme,
// should be communicated using `ThemeMode`.
@strict_audit(bug="https://fxbug.dev/467128325", state="PENDING_REVIEW")
type ThemeType = strict enum {
    /// When `ThemeType` is set to `DEFAULT` it is up to the specific
    /// [product](https://fuchsia.dev/fuchsia-src/concepts/build_system/boards_and_products#products)
    /// to determine what that actually means.
    DEFAULT = 0;
    LIGHT = 1;
    DARK = 2;
};

// Specifies options that pertain to selection or display of a theme in the
// UI. If a specific theme needs to be specified, that should be done using
// `ThemeType`.
@strict_audit(bug="https://fxbug.dev/467128325", state="PENDING_REVIEW")
type ThemeMode = strict bits {
    /// Product can choose a theme based on ambient cues.
    AUTO = 0x01;
};
