// 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.
@available(added=7)
library fuchsia.camera2.hal;

using fuchsia.camera2;
using fuchsia.sysmem;
using zx;

/// Maximum number of configurations per device.
const MAX_CONFIGURATIONS uint64 = 256;

/// Maximum number of streams per config.
const MAX_STREAMS uint64 = 64;

/// Represents one stream within a particular configuration.
type StreamConfig = struct {
    frame_rate fuchsia.camera2.FrameRate;
    /// `constraints` should allow for all the image formats listed in image_formats.
    constraints fuchsia.sysmem.BufferCollectionConstraints;

    /// Properties of the stream:
    properties fuchsia.camera2.StreamProperties;

    /// We need to specify both the constraints & the image formats because
    /// there are fixed set of resolutions supported by the Camera Controller
    /// so a range within the `constraints` won't be sufficient.
    /// Some streams support multiple resolutions for same configuration
    /// We would need to change the resolution runtime, without stopping the
    /// streaming. This provides a list of resolutions a stream would be providing.
    /// At least one format must be provided.
    image_formats vector<fuchsia.sysmem.ImageFormat_2>:fuchsia.camera2.MAX_IMAGE_FORMATS;
};

/// Represents one configuration
type Config = struct {
    // One configuration could have multiple streams.
    stream_configs vector<StreamConfig>:MAX_STREAMS;
};

/// This is the interface to the camera driver
/// which allows setting up a given configuration
/// and setting up a stream.
@discoverable
closed protocol Controller {
    /// Returns the next available configuration which the camera driver supports.
    /// Returns ZX_ERR_STOP if no new configurations are available.
    strict GetNextConfig() -> (struct {
        config box<Config>;
        status zx.Status;
    });

    /// Set a particular configuration and create the requested stream.
    /// `config_index` : Configuration index from the vector which needs to be applied.
    /// `stream_index` : Stream index from the vector of streams provided within a config.
    /// `stream` : Stream channel for the stream requested
    /// `image_format_index` : Image format index which needs to be set up upon creation.
    /// If there is already an active configuration which is different than the one
    /// which is requested to be set, then the HAL will be closing all existing streams
    /// and honor this new setup call.
    /// If the new stream requested is already part of the existing running configuration
    /// the HAL will just be creating this new stream while the other stream still exists as is.
    strict CreateStream(resource struct {
        config_index uint32;
        stream_index uint32;
        image_format_index uint32;
        stream server_end:fuchsia.camera2.Stream;
    });

    /// Enable/Disable Streaming
    strict EnableStreaming();
    strict DisableStreaming();

    // Get identifying information about the device:
    strict GetDeviceInfo() -> (struct {
        info fuchsia.camera2.DeviceInfo;
    });
};
