///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017-2023 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
// Not a Contribution.
// Apache license notifications and license are retained
// for attribution purposes only.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013 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.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  chioverride.h
/// @brief CamX Hardware Interface (CHI) Override definition
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CHIOVERRIDE_H
#define CHIOVERRIDE_H

#include "camera3.h"
#include "camera_common.h"
#include "camxcdktypes.h"
#include "chi.h"
#include "chicommon.h"

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

#pragma pack(push, 8)

/** @addtogroup chi_common_hal3_overrides
@{ */

/// @brief Callback functions implemented in the driver called by the CHI override module.
typedef struct /** @cond */ chi_hal_ops /** @endcond */
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond process_capture_result @endcond
    ///
    /// @brief Defines the prototype for the callback method used to send completed capture results to the framework.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void (*process_capture_result)(
        const camera3_device_t*,
        const camera3_capture_result_t*);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond notify_result @endcond
    ///
    /// @brief Defines the prototype for the asynchronous notification callback method from the camera driver to the
    ///        framework.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void (*notify_result)(
        const camera3_device_t*,
        const camera3_notify_msg_t*);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond trigger_system_event @endcond
    ///
    /// @brief Defines the prototype for the dump notification callback method from the framework.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void (*trigger_system_event)(
        const camera3_device_t*,
        const camera3_notify_msg_t*);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond request_stream_buffers @endcond
    ///
    /// @brief Defines the prototype used to request a stream buffer from the framework.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    camera3_buffer_request_status_t (*request_stream_buffers)(
        const camera3_device_t*,
        uint32_t,
        const camera3_buffer_request_t*,
        uint32_t*,
        camera3_stream_buffer_ret_t*);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond return_stream_buffers @endcond
    ///
    /// @brief Defines the prototype used to return a stream buffer to the framework.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void (*return_stream_buffers)(
        const camera3_device_t*,
        uint32_t,
        const camera3_stream_buffer_t* const*);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond update_perf_settings @endcond
    ///
    /// @brief Defines the prototype used to update perf settings.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    uint32_t (*update_perf_settings)(
        const camera3_device_t*,
        camera_metadata_t*);
} chi_hal_ops_t;

/// @brief Callback functions used to call from the driver into the override module.
typedef struct chi_hal_callback_ops
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_get_num_cameras @endcond
    ///
    /// @brief Gets the number of cameras.
    ///
    /// @param[out] numFwCameras       Pointer to the number of cameras to return to the firmware.
    /// @param[out] numLogicalCameras  Pointer to the number of logical cameras.
    ///
    /// @return Number of cameras.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void (*chi_get_num_cameras)(
        uint32_t* numFwCameras,
        uint32_t* numLogicalCameras);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_get_camera_info @endcond
    ///
    /// @datatypes
    /// #CDKGetInfoCmd
    ///
    /// @brief Gets camera information for a specified camera ID.
    ///
    /// @param[in] cameraId     Unique ID of the camera.
    /// @param[in] pCameraInfo  Pointer to the camera information.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    int (*chi_get_camera_info)(
        int                      cameraId,
        struct camera_info*      pCameraInfo);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_get_info @endcond
    ///
    /// @brief Generic interface for retrieving information from the override module.
    ///
    /// @datatypes
    /// #CDKGetInfoCmd
    ///
    /// @param[in] infoCmd       Camera type (logical or physical) for which the information is to be retrieved.
    /// @param[in] inputParams   Pointer to the input parameters.
    /// @param[in] outputParams  Pointer to the output parameters.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*chi_get_info)(
        CDKGetInfoCmd       infoCmd,
        void*               inputParams,
        void*               outputParams);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_initialize_override_session @endcond
    ///
    /// @brief Callback for initializing an override session.
    ///
    /// @datatypes
    /// #chi_hal_ops_t
    ///
    /// @param[in]  cameraId         Unique ID of the camera.
    /// @param[in]  camera3_device   Pointer to the instance of the CHI driver.
    /// @param[in]  hal_ops          Pointer to the framework callback functions called by the CHI override module.
    /// @param[in]  stream_config    Pointer to the details about the streams being processed.
    /// @param[out] override_config  Pointer to the override configuration. \n @vertspace{3}
    ///                              This value is returned as TRUE only if the override module is to use custom pipelines for
    ///                              the specified configuration. \n @vertspace{3}
    ///                              If the override module is to use the default functionality provided by the driver, it
    ///                              must return FALSE.
    /// @param[out] priv             Double pointer to the private data that is exchanged between the camera driver and CHI
    ///                              driver. \n @vertspace{3}
    ///                              This pointer is passed back into every function in chi_hal_callback_ops_t, and it must
    ///                              be cast to the appropriate internal structure by the override module. \n @vertspace{3}
    ///                              NULL is a valid return value. It is required if the pipeline parameter is not set to a
    ///                              valid pipeline handle.
    ///
    /// @detdesc
    /// The driver calls this function when the HAL receives a stream configuration from the framework.
    /// @par
    /// The override module inspects the stream configuration and determines if it will use a custom live stream pipeline as
    /// specified by the module, or if it will use a default pipeline as specified by the driver.
    /// Default live stream pipelines are not supported with custom offline pipelines.
    /// @par
    /// Any memory required to manage a per-session state can be allocated in this function. A private pointer to the state,
    /// received as output from this function, is passed into the override module on every call to allow for multiple
    /// concurrent camera devices.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*chi_initialize_override_session)(
        uint32_t                        cameraId,
        const camera3_device_t*         camera3_device,
        const chi_hal_ops_t*            hal_ops,
        camera3_stream_configuration_t* stream_config,
        int*                            override_config,
        void**                          priv);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_finalize_override_session @endcond
    ///
    /// @brief Callback for finalizing an override session.
    ///
    /// @param[in] camera3_device  Pointer to the instance of the CHI driver.
    /// @param[in] priv            Pointer to the private data for the module.
    ///
    /// @detdesc
    /// This function is optional, and the function pointer is not required in chi_hal_callback_ops_t during the
    /// chi_hal_override_entry() call.
    /// @par
    /// The driver calls this function after it finishes initializing itself at the end of configure_streams(), but only if the
    /// override module returned a valid pipeline handle in chi_initialize_override_session().
    /// @par
    /// This callback allows the override module to create any offline pipelines that it might need to use for the use case.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*chi_finalize_override_session)(
        const camera3_device_t* camera3_device,
        void*                   priv);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_teardown_override_session @endcond
    ///
    /// @brief Tears down a session.
    ///
    /// @param[in] camera3_device  Pointer to the instance of the CHI driver.
    /// @param[in] session         Handle of the session.
    /// @param[in] priv            Pointer to the private data for the module.
    ///
    /// @detdesc
    /// The driver calls this function when the HAL receives configure_streams() from the framework with a different stream
    /// configuration. To avoid wasting system resources, the old session is torn down before a new session is started. Any
    /// memory that was allocated for the override session can be destroyed.
    ///
    /// @return None. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void (*chi_teardown_override_session)(
        const camera3_device_t* camera3_device,
        uint64_t                session,
        void*                   priv);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_override_process_request @endcond
    ///
    /// @brief Processes an override request.
    ///
    /// @param[in] camera3_device   Pointer to the instance of the CHI driver.
    /// @param[in] capture_request  Pointer to the details about the request.
    /// @param[in] priv             Pointer to the private data for the module.
    ///
    /// @detdesc
    /// This function is called only when the CHI override module specifies a custom pipeline in chi_hal_override_entry().
    /// @par
    /// When a custom pipeline is active, this function is called for every framework request. The override module plugin
    /// assumes complete responsibility for processing this request and calling the notification functions for the filled
    /// buffers and metadata.
    /// @par
    /// When a framework request is received by the CHI override module, it can modify the request, create additional requests
    /// for multi-frame features, and forward these requests to the CHI layer in the driver. The request is submitted to the
    /// appropriate pipeline via CHI for processing by the driver.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}).
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*chi_override_process_request)(
        const camera3_device_t*     camera3_device,
        camera3_capture_request_t*  capture_request,
        void*                       priv);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_extend_open @endcond
    ///
    /// @brief Allows override processing when the HAL performs an open call.
    ///
    /// @param[in] cameraId  Unique ID of the logical camera.
    /// @param[in] priv      Pointer to the private data for the module.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*chi_extend_open)(
        uint32_t    cameraId,
        void*       priv);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_extend_close @endcond
    ///
    /// @brief Allows override processing when the HAL performs a close call.
    ///
    /// @param[in] cameraId  Unique ID of the logical camera.
    ///
    /// @return None.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void(*chi_extend_close)(
        uint32_t    cameraId);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_remap_camera_id @endcond
    ///
    /// @brief Allows an override to detect a special camera ID.
    ///
    /// @datatypes
    /// #CameraIdRemapMode
    ///
    /// @param[in] frameworkCameraId  Unique camera ID from the framework.
    /// @param[in] mode               Type of remapping that was requested.
    ///
    /// @return Logical Id and physical Id.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    std::pair<uint32_t, uint32_t> (*chi_remap_camera_id)(
        uint32_t            frameworkCameraId,
        CameraIdRemapMode   mode);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_modify_settings @endcond
    ///
    /// @brief Allows various override-specific settings to be toggled.
    ///
    /// @return None. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void (*chi_modify_settings)();

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_get_default_request_settings @endcond
    ///
    /// @brief Gets the default request settings.
    ///
    /// @param[in] cameraId         Unique ID of the camera.
    /// @param[in] requestTemplate  Android request template.
    /// @param[in] settings         Double pointer to the request settings filled in by the override.
    ///
    /// @detdesc
    /// The override can provide any vendor tag-specific request settings to be added to the default request settings.
    ///
    /// @return None.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*chi_get_default_request_settings)(
        uint32_t                  cameraId,
        int                       requestTemplate,
        const camera_metadata_t** settings);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_override_flush @endcond
    ///
    /// @brief Allows override processing when the HAL performs a flush call.
    ///
    /// @param[in] camera3_device  Pointer to the instance of the CHI driver.
    ///
    /// @return None. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*chi_override_flush)(
        const camera3_device_t*     camera3_device);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_override_signal_stream_flush @endcond
    ///
    /// @brief Allows override processing when the HAL performs a flush call on a signal stream.
    ///
    /// @param[in] camera3_device     Pointer to the camera3_device instance of Chi driver.
    /// @param[in] num_streams        The number of streams to be flushed.
    /// @param[in] streams            The array of streams to be flushed.
    ///
    /// @return None.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*chi_override_signal_stream_flush)(
        const camera3_device_t*         camera3_device,
        uint32_t                        num_streams,
        const camera3_stream_t* const*  streams);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_override_dump @endcond
    ///
    /// @brief Allows override processing when the HAL performs a dump call.
    ///
    /// @param[in] pMessageDescriptor  Pointer to the message descriptor associated with the system event.
    /// @param[in] camera3_device      Pointer to the instance of the CHI driver.
    /// @param[in] textLogFd           File descriptor for text logging.
    /// @param[in] binaryLogFd         File descriptor for binary logging.
    /// @param[in] indent              Indentation to be kept.
    ///
    /// @return #CDKResultSuccess or an error code (see Section @xref{hdr:resultMessages}). @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*chi_override_dump)(
       VOID*                   pMessageDescriptor,
       const camera3_device_t* camera3_device,
       INT                     textLogFd,
       UINT64                  binaryLogFd,
       UINT32                  indent);
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_get_physical_camera_info @endcond
    ///
    /// @brief Gets the camera metadata associated with a physical camera ID.
    ///
    /// @param[in] physCamId  Camera ID for the physical device.
    ///
    /// @detdesc
    /// This function is only called on hidden physical cameras within an exposed logical camera.
    ///
    /// @return Valid ID upon success, or NULL upon failure.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    const camera_metadata_t* (*chi_get_physical_camera_info)(
        UINT32         physCamId);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_is_stream_combination_supported @endcond
    ///
    /// @brief Checks whether the camera supports a given camera stream combination.
    ///
    /// @datatypes
    /// camera_stream_combination_t
    ///
    /// @param[in] cameraId  Unique ID of the camera.
    /// @param[in] rStreams  Combination of the input and output streams to be checked.
    ///
    /// @return TRUE if supported. Otherwise, FALSE.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BOOL (*chi_is_stream_combination_supported)(
        UINT32                             cameraId,
        const camera_stream_combination_t& rStreams);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_is_concurrent_stream_combination_supported @endcond
    ///
    /// @brief Determines whether all cameras in a given configuration are supported concurrently.
    ///
    /// @param[in] numCombinations          Number of concurrent camera combinations.
    /// @param[in] pConcurrentCamerasCombo  Pointer to the supported combinations.
    ///
    /// @return TRUE if supported; otherwise, FALSE. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BOOL (*chi_is_concurrent_stream_combination_supported)(
        UINT32                                numCombinations,
        const cameraid_stream_combination_t*  pConcurrentCombinations);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond chi_override_repeating_request_end @endcond
    ///
    /// @brief Allows override processing when the HAL performs a repeating request end call.
    ///
    /// @datatypes
    /// camera3_device_t
    /// camera3_stream_t
    ///
    /// @param[in] camera3_device     Pointer to the camera3_device instance of Chi driver.
    /// @param[in] inFrameNumber     The input frame number
    /// @param[in] numStreams        The number of streams for requestId end.
    /// @param[in] streams            The array of streams for requestId end.
    ///
    /// @return None.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*chi_override_repeating_request_end)(
        const camera3_device_t*         camera3_device,
        INT32                           inFrameNumber,
        uint32_t                        numStreams,
        const camera3_stream_t* const*  streams);

} /** @cond */ chi_hal_callback_ops_t /** @endcond */;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @cond chi_hal_override_entry @endcond
///
/// @brief Entry point called by the CHI driver to initialize the HAL override module.
///
/// @datatypes
/// chi_hal_callback_ops_t
///
/// @param[in,out] callbacks  Pointer to the callbacks that the driver must make into the override module. The override module
///                           must fill in these function pointers.
///
/// @detdesc
/// For a driver to initialize the override interface, every com.vendor.chi.override.so must export this function.
/// @par
/// This function is called during the camera server initialization, which occurs when the HAL performs a process start.
/// In addition to communicating the necessary function pointers between the driver and the override module, the override
/// module can perform any initialization work that must be done at boot time. Initialization can include loading different SO
/// files, which provide additional functionality.
/// @par
/// Any operations must not be specific to a session, and any global variables stored in the override module must be protected
/// against multiple sessions accessing it at the same time.
///
/// @return None. @newpage
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CDK_VISIBILITY_PUBLIC void chi_hal_override_entry(
    chi_hal_callback_ops_t* callbacks);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @cond chi_hal_query_vendertag @endcond
///
/// @brief Entry point called by the CHI driver to query vendor tags that are defined in the CHI extension.
///
/// @datatypes
/// #CHIQUERYVENDORTAG
///
/// @param[in,out] p_query_vendor_tags  Pointer to the vendor tag information.
///
/// @detdesc
/// This function is optional for every com.vendor.chi.override.so for a driver to query the vendor tags from an override.
/// @par
/// This function is called during camera server initialization, which occurs when the HAL performs a process start. This
/// function should return only the vendor tag information; no other operation is allowed at this point.
///
/// @return TRUE if successful. Otherwise, FALSE.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CDK_VISIBILITY_PUBLIC CDKResult chi_hal_query_vendertag(
    CHIQUERYVENDORTAG* p_query_vendor_tags);

/** @} */ /* end_addtogroup chi_common_hal3_overrides */

#pragma pack(pop)

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // CHIOVERRIDE_H
