/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.camera.common@1.0;

/**
 * Common enumeration and structure definitions for all HALs under
 * android.hardware.camera
 */

/**
 * Status codes for camera HAL method calls.
 *
 */
enum Status : uint32_t {
    /**
     * Method call succeeded
     */
    OK = 0,

    /**
     * One of the arguments to the method call is invalid. For example,
     * the camera ID is unknown.
     */
    ILLEGAL_ARGUMENT = 1,

    /**
     * The specified camera device is already in use
     */
    CAMERA_IN_USE = 2,

    /**
     * The HAL cannot support more simultaneous cameras in use.
     */
    MAX_CAMERAS_IN_USE = 3,

    /**
     * This HAL does not support this method.
     */
    METHOD_NOT_SUPPORTED = 4,

    /**
     * The specified camera device does not support this operation.
     */
    OPERATION_NOT_SUPPORTED = 5,

    /**
     * This camera device is no longer connected or otherwise available for use
     */
    CAMERA_DISCONNECTED = 6,

    /**
     * The HAL has encountered an internal error and cannot complete the
     * request.
     */
    INTERNAL_ERROR = 7
};

/**
 * Possible states that the flash unit on a closed camera device can be set to
 * via the ICameraProvider::setTorchMode() method.
 */
enum TorchMode : uint32_t {
    OFF = 0, // Turn off the flash
    ON  = 1  // Turn on the flash to torch mode
};

/**
 * Camera metadata type - duplicated from VNDK libcamera_metadata for vendor tag
 * definitions.
 */
enum CameraMetadataType : uint32_t {
    // Unsigned 8-bit integer (uint8_t)
    BYTE = 0,
    // Signed 32-bit integer (int32_t)
    INT32 = 1,
    // 32-bit float (float)
    FLOAT = 2,
    // Signed 64-bit integer (int64_t)
    INT64 = 3,
    // 64-bit float (double)
    DOUBLE = 4,
    // A 64-bit fraction (camera_metadata_rational_t)
    RATIONAL = 5
};

/**
 * A single vendor-unique metadata tag.
 * The full name of the tag is <sectionName>.<tagName>
 */
struct VendorTag {
    uint32_t tagId; // Tag identifier, must be >= TagBoundaryId::VENDOR
    string tagName; // Name of tag, not including section name
    CameraMetadataType tagType;
};

/**
 * A set of related vendor tags.
 */
struct VendorTagSection {
    string sectionName; // Section name; must be namespaced within vendor's name
    vec<VendorTag> tags; // List of tags in this section
};

enum TagBoundaryId : uint32_t {
    AOSP    = 0x0,         // First valid tag id for android-defined tags
    VENDOR  = 0x80000000u  // First valid tag id for vendor extension tags
};

/**
 * CameraDeviceStatus
 *
 * The current status of a camera device, as sent by a camera provider HAL
 * through the ICameraProviderCallback::cameraDeviceStatusChange() call.
 *
 * At startup, the camera service must assume all internal camera devices listed
 * by ICameraProvider::getCameraIdList() are in the PRESENT state. The provider
 * must invoke ICameraProviderCallback::cameraDeviceStatusChange to inform the
 * service of any initially NOT_PRESENT internal devices, and of any PRESENT
 * external camera devices, as soon as the camera service has called
 * ICameraProvider::setCallback().
 *
 * Allowed state transitions:
 *      PRESENT            -> NOT_PRESENT
 *      NOT_PRESENT        -> ENUMERATING
 *      NOT_PRESENT        -> PRESENT
 *      ENUMERATING        -> PRESENT
 *      ENUMERATING        -> NOT_PRESENT
 */
enum CameraDeviceStatus : uint32_t {
    /**
     * The camera device is not currently connected, and trying to reference it
     * in provider method calls must return status code ILLEGAL_ARGUMENT.
     *
     */
    NOT_PRESENT = 0,

    /**
     * The camera device is connected, and opening it is possible, as long as
     * sufficient resources are available.
     *
     * By default, the framework must assume all devices returned by
     * ICameraProvider::getCameraIdList() are in this state.
     */
    PRESENT = 1,

    /**
     * The camera device is connected, but it is undergoing enumeration and
     * startup, and so opening the device must return CAMERA_IN_USE.
     *
     * Attempting to call ICameraProvider::getCameraCharacteristics() must
     * succeed, however.
     */
    ENUMERATING = 2,

};

/**
 * TorchModeStatus:
 *
 * The current status of the torch mode on a given camera device, sent by a
 * camera provider HAL via the ICameraProviderCallback::TorchModeStatusChange()
 * call.
 *
 * The torch mode status of a camera device is applicable only when the camera
 * device is present. The camera service must not call
 * ICameraProvider::setTorchMode() to turn on torch mode of a camera device if
 * the camera device is not present. At camera service startup time, the
 * framework must assume torch modes are in the AVAILABLE_OFF state if the
 * camera device is present and the camera characteristics entry
 * android.flash.info.available is reported as true via
 * ICameraProvider::getCameraCharacteristics() call. The same is assumed for
 * external camera devices when they are initially connected.
 *
 * The camera service requires the following behaviors from the camera provider
 * HAL when a camera device's status changes:
 *
 *  1. A previously-disconnected camera device becomes connected. After
 *      ICameraProviderCallback::CameraDeviceStatusChange() is invoked to inform
 *      the camera service that the camera device is present, the framework must
 *      assume the camera device's torch mode is in AVAILABLE_OFF state if it
 *      has a flash unit. The camera provider HAL does not need to invoke
 *      ICameraProviderCallback::TorchModeStatusChange() unless the flash unit
 *      is unavailable to use by ICameraProvider::setTorchMode().
 *
 *  2. A previously-connected camera becomes disconnected. After
 *      ICameraProviderCallback::CameraDeviceStatusChange() is invoked to inform
 *      the camera service that the camera device is not present, the framework
 *      must not call ICameraProvider::setTorchMode() for the disconnected camera
 *      device until it is connected again. The camera provider HAL does not
 *      need to invoke ICameraProviderCallback::TorchModeStatusChange()
 *      separately to inform that the flash unit has become NOT_AVAILABLE.
 *
 *  3. openCameraDevice() or openCameraDeviceVersion() is called to open a
 *      camera device. The camera provider HAL must invoke
 *      ICameraProviderCallback::TorchModeStatusChange() for all flash units
 *      that have entered NOT_AVAILABLE state and can not be turned on by
 *      calling ICameraProvider::setTorchMode() due to this open() call.
 *      openCameraDevice() must not trigger AVAILABLE_OFF before NOT_AVAILABLE
 *      for all flash units that have become unavailable.
 *
 *  4. ICameraDevice.close() is called to close a camera device. The camera
 *      provider HAL must call ICameraProviderCallback::torchModeStatusChange()
 *      for all flash units that have now entered the AVAILABLE_OFF state and
 *      can be turned on by calling ICameraProvider::setTorchMode() again because
 *      of sufficient new camera resources being freed up by this close() call.
 *
 *  Note that the camera service calling ICameraProvider::setTorchMode()
 *  successfully must trigger AVAILABLE_OFF or AVAILABLE_ON callback for the
 *  given camera device. Additionally it must trigger AVAILABLE_OFF callbacks
 *  for other previously-on torch modes if HAL cannot keep multiple devices'
 *  flashlights on simultaneously.
 */
enum TorchModeStatus : uint32_t {
    /**
     * The flash unit is no longer available and the torch mode can not be
     * turned on by calling setTorchMode(). If the torch mode was AVAILABLE_ON,
     * the flashlight must be turned off by the provider HAL before the provider
     * HAL calls torchModeStatusChange().
     */
    NOT_AVAILABLE = 0,

    /**
     * A torch mode has become off and is available to be turned on via
     * ICameraProvider::setTorchMode(). This may happen in the following
     * cases:
     *   1. After the resources to turn on the torch mode have become available.
     *   2. After ICameraProvider::setTorchMode() is called to turn off the torch
     *      mode.
     *   3. After the camera service turned on the torch mode for some other
     *      camera device and the provider HAL had to turn off the torch modes
     *      of other camera device(s) that were previously on, due to lack of
     *      resources to keep them all on.
     */
    AVAILABLE_OFF = 1,

    /**
     * A torch mode has become on and is available to be turned off via
     * ICameraProvider::setTorchMode(). This can happen only after
     * ICameraProvider::setTorchMode() has been called to turn on the torch mode.
     */
    AVAILABLE_ON = 2,

};

/**
 * CameraResourceCost:
 *
 * Structure defining the abstract resource cost of opening a camera device,
 * and any usage conflicts between multiple camera devices.
 *
 * Obtainable via ICameraDevice::getResourceCost()
 */
struct CameraResourceCost {
    /**
     * The total resource "cost" of using this camera, represented as an integer
     * value in the range [0, 100] where 100 represents total usage of the
     * shared resource that is the limiting bottleneck of the camera subsystem.
     * This may be a very rough estimate, and is used as a hint to the camera
     * service to determine when to disallow multiple applications from
     * simultaneously opening different cameras advertised by the camera
     * service.
     *
     * The camera service must be able to simultaneously open and use any
     * combination of camera devices exposed by the HAL where the sum of
     * the resource costs of these cameras is <= 100. For determining cost,
     * each camera device must be assumed to be configured and operating at
     * the maximally resource-consuming framerate and stream size settings
     * available in the configuration settings exposed for that device through
     * the camera metadata.
     *
     * The camera service may still attempt to simultaneously open combinations
     * of camera devices with a total resource cost > 100. This may succeed or
     * fail. If this succeeds, combinations of configurations that are not
     * supported due to resource constraints from having multiple open devices
     * must fail during the configure calls. If the total resource cost is <=
     * 100, open and configure must never fail for any stream configuration
     * settings or other device capabilities that would normally succeed for a
     * device when it is the only open camera device.
     *
     * This field may be used to determine whether background applications are
     * allowed to use this camera device while other applications are using
     * other camera devices. Note: multiple applications must never be allowed
     * by the camera service to simultaneously open the same camera device.
     *
     * Example use cases:
     *
     * Ex. 1: Camera Device 0 = Back Camera
     *        Camera Device 1 = Front Camera
     *   - Using both camera devices causes a large framerate slowdown due to
     *     limited ISP bandwidth.
     *
     *   Configuration:
     *
     *   Camera Device 0 - resourceCost = 51
     *                     conflicting_devices = empty
     *   Camera Device 1 - resourceCost = 51
     *                     conflicting_devices = empty
     *
     *   Result:
     *
     *   Since the sum of the resource costs is > 100, if a higher-priority
     *   application has either device open, no lower-priority applications must
     *   be allowed by the camera service to open either device. If a
     *   lower-priority application is using a device that a higher-priority
     *   subsequently attempts to open, the lower-priority application must be
     *   forced to disconnect the the device.
     *
     *   If the highest-priority application chooses, it may still attempt to
     *   open both devices (since these devices are not listed as conflicting in
     *   the conflicting_devices fields), but usage of these devices may fail in
     *   the open or configure calls.
     *
     * Ex. 2: Camera Device 0 = Left Back Camera
     *        Camera Device 1 = Right Back Camera
     *        Camera Device 2 = Combined stereo camera using both right and left
     *                          back camera sensors used by devices 0, and 1
     *        Camera Device 3 = Front Camera
     *   - Due to do hardware constraints, up to two cameras may be open at
     *     once. The combined stereo camera may never be used at the same time
     *     as either of the two back camera devices (device 0, 1), and typically
     *     requires too much bandwidth to use at the same time as the front
     *     camera (device 3).
     *
     *   Configuration:
     *
     *   Camera Device 0 - resourceCost = 50
     *                     conflicting_devices = { 2 }
     *   Camera Device 1 - resourceCost = 50
     *                     conflicting_devices = { 2 }
     *   Camera Device 2 - resourceCost = 100
     *                     conflicting_devices = { 0, 1 }
     *   Camera Device 3 - resourceCost = 50
     *                     conflicting_devices = empty
     *
     *   Result:
     *
     *   Based on the conflicting_devices fields, the camera service guarantees
     *   that the following sets of open devices must never be allowed: { 1, 2
     *   }, { 0, 2 }.
     *
     *   Based on the resourceCost fields, if a high-priority foreground
     *   application is using camera device 0, a background application would be
     *   allowed to open camera device 1 or 3 (but would be forced to disconnect
     *   it again if the foreground application opened another device).
     *
     *   The highest priority application may still attempt to simultaneously
     *   open devices 0, 2, and 3, but the HAL may fail in open or configure
     *   calls for this combination.
     *
     * Ex. 3: Camera Device 0 = Back Camera
     *        Camera Device 1 = Front Camera
     *        Camera Device 2 = Low-power Front Camera that uses the same sensor
     *                          as device 1, but only exposes image stream
     *                          resolutions that can be used in low-power mode
     *  - Using both front cameras (device 1, 2) at the same time is impossible
     *    due a shared physical sensor. Using the back and "high-power" front
     *    camera (device 1) may be impossible for some stream configurations due
     *    to hardware limitations, but the "low-power" front camera option may
     *    always be used as it has special dedicated hardware.
     *
     *   Configuration:
     *
     *   Camera Device 0 - resourceCost = 100
     *                     conflicting_devices = empty
     *   Camera Device 1 - resourceCost = 100
     *                     conflicting_devices = { 2 }
     *   Camera Device 2 - resourceCost = 0
     *                     conflicting_devices = { 1 }
     *   Result:
     *
     *   Based on the conflicting_devices fields, the camera service guarantees
     *   that the following sets of open devices must never be allowed:
     *   { 1, 2 }.
     *
     *   Based on the resourceCost fields, only the highest priority application
     *   may attempt to open both device 0 and 1 at the same time. If a
     *   higher-priority application is not using device 1 or 2, a low-priority
     *   background application may open device 2 (but must be forced to
     *   disconnect it if a higher-priority application subsequently opens
     *   device 1 or 2).
     */
    uint32_t resourceCost;

    /**
     * An array of camera device IDs indicating other devices that cannot be
     * simultaneously opened while this camera device is in use.
     *
     * This field is intended to be used to indicate that this camera device
     * is a composite of several other camera devices, or otherwise has
     * hardware dependencies that prohibit simultaneous usage. If there are no
     * dependencies, an empty list may be returned to indicate this.
     *
     * The camera service must never simultaneously open any of the devices
     * in this list while this camera device is open.
     *
     */
    vec<string> conflictingDevices;

};
