/**
 * @file hv_mw_OsdEvent.c
 * @brief osd MiddleWare event c file.
 * @details This file provides the following functions: \n
 *          (1) Osd key event process functions (key repeat & key hold) \n
 *          (2) Osd event process functions \n
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-09-01
 * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author       <th>Date            <th>Change Description
 * <tr><td>shanpeng     <td>2022-09-01      <td>create
 * </table>
 */

#include "hv_comm_DataBase.h"
#include "hv_comm_Timer.h"
#include "hv_mw_OsdComm.h"
#include "hv_mw_OsdLog.h"
#include "hv_mw_OsdEvent.h"
#include "hv_mw_SystemManager.h"

//#define OSD_USE_HW_TIMER

#define OSD_REMINDER_NUM        (4)

typedef struct _OsdEventManager {
    /* 当前按键键值 */
    OsdEvtKeyValue enKeyValue;
    /* 长按键键值 */
    OsdEvtKeyValue enHoldKeyValue;

    /* 按键可重复标志 */
    USHORT16 usKeyRepeatFlag;
    /* 按键可长按标志 */
    USHORT16 usKeyHoldFlag;
    /* 按键重复状态标志 */
    USHORT16 usKeyRepeatStateFlag;
    /* 按键长按状态标志 */
    USHORT16 usKeyHoldStateFlag;
    /* 按键禁用状态标志 */
    USHORT16 usKeyDisableStateFlag;
    /* 按键重复周期 */
    UINT32 uiKeyRepeatPeriodMs;
    /* 按键长按时间 */
    UINT32 uiKeyHoldPeriodMs[OSDEVT_KEY_MAX];

    UINT64 ullCacheFlag;
    UINT64 ullCacheOnceFlag;
    UINT64 ullForceProcessFlag;
    UINT64 ullLogoingProcessFlag;

#ifdef OSD_USE_HW_TIMER
    /* 按键重复timer */
    HvCommonHwTimer* pstKeyRepeatTimer;
    /* 按键长按timer */
    HvCommonHwTimer* pstKeyHoldTimer;
    /* 自动刷新timer */
    HvCommonHwTimer* apstAutoRefreshTimerArray[SCENE_ID_MAX];
    /* 自动关闭timer */
    HvCommonHwTimer* apstAutoCloseTimerArray[SCENE_ID_MAX];
    /* Logo timer */
    HvCommonHwTimer* pstLogoTimer;
#else
    /* 按键重复timer */
    HV_TIMER_S* pstKeyRepeatTimer;
    /* 按键长按timer */
    HV_TIMER_S* pstKeyHoldTimer;
    /* 自动刷新timer */
    HV_TIMER_S* apstAutoRefreshTimerArray[SCENE_ID_MAX];
    /* 自动关闭timer */
    HV_TIMER_S* apstAutoCloseTimerArray[SCENE_ID_MAX];
    /* Logo timer */
    HV_TIMER_S* pstLogoTimer;
#endif
    /* 定时提醒timer */
    HV_TIMER_S* apstReminderTimerArray[OSD_REMINDER_NUM];

#ifdef HV_SCALER_DEBUG_VERSION
    HvCommonHwTimer* pstOsdTestTimer;
#ifdef OSD_USE_HW_TIMER
    HvCommonHwTimer* pstOsdAutoTestTimer;
#else
    HV_TIMER_S* pstOsdAutoTestTimer;
#endif
    BOOL bIsTesting;
    UINT64 ullSyncTick;
    BOOL bDisableAutoClose;
#endif
} OsdEventManager;

static OsdEventManager s_stOsdEventData;

#define SET_REPEATABLE_FLAG(x)           (s_stOsdEventData.usKeyRepeatFlag |= (BIT_0 << (x)))
#define SET_HOLDABLE_FLAG(x)             (s_stOsdEventData.usKeyHoldFlag |= (BIT_0 << (x)))
#define GET_REPEATABLE_FLAG(x)           ((s_stOsdEventData.usKeyRepeatFlag >> (x)) & BIT_0)
#define GET_HOLDABLE_FLAG(x)             ((s_stOsdEventData.usKeyHoldFlag >> (x)) & BIT_0)
#define CLEAR_REPEATABLE_FLAG(x)         (s_stOsdEventData.usKeyRepeatFlag &= ~((USHORT16)BIT_0 << (x)))
#define CLEAR_HOLDABLE_FLAG(x)           (s_stOsdEventData.usKeyHoldFlag &= ~((USHORT16)BIT_0 << (x)))
#define CLEAR_REPEATABLE_FLAG_ALL()      (s_stOsdEventData.usKeyRepeatFlag = 0x00)
#define CLEAR_HOLDABLE_FLAG_ALL()        (s_stOsdEventData.usKeyHoldFlag = 0x00)

#define SET_REPEAT_STATE_FLAG(x)         (s_stOsdEventData.usKeyRepeatStateFlag |= (BIT_0 << (x)))
#define SET_HOLD_STATE_FLAG(x)           (s_stOsdEventData.usKeyHoldStateFlag |= (BIT_0 << (x)))
#define SET_DISABLE_STATE_FLAG(x)        (s_stOsdEventData.usKeyDisableStateFlag |= (BIT_0 << (x)))
#define GET_REPEAT_STATE_FLAG(x)         ((s_stOsdEventData.usKeyRepeatStateFlag >> (x)) & BIT_0)
#define GET_HOLD_STATE_FLAG(x)           ((s_stOsdEventData.usKeyHoldStateFlag >> (x)) & BIT_0)
#define GET_DISABLE_STATE_FLAG(x)        ((s_stOsdEventData.usKeyDisableStateFlag >> (x)) & BIT_0)
#define KEY_IS_REPEATING()               (!(s_stOsdEventData.usKeyRepeatStateFlag == 0))
#define KEY_IS_HOLDING()                 (!(s_stOsdEventData.usKeyHoldStateFlag == 0))
#define CLEAR_REPEAT_STATE_FLAG(x)       (s_stOsdEventData.usKeyRepeatStateFlag &= ~((USHORT16)BIT_0 << (x)))
#define CLEAR_HOLD_STATE_FLAG(x)         (s_stOsdEventData.usKeyHoldStateFlag &= ~((USHORT16)BIT_0 << (x)))
#define CLEAR_DISABLE_STATE_FLAG(x)      (s_stOsdEventData.usKeyDisableStateFlag &= ~((USHORT16)BIT_0 << (x)))
#define CLEAR_REPEAT_STATE_FLAG_ALL()    (s_stOsdEventData.usKeyRepeatStateFlag = 0x00)
#define CLEAR_HOLD_STATE_FLAG_ALL()      (s_stOsdEventData.usKeyHoldStateFlag = 0x00)
#define CLEAR_DISABLE_STATE_FLAG_ALL()   (s_stOsdEventData.usKeyDisableStateFlag = 0x00)

#define SET_EVENT_CACHABLE_FLAG(x)           (s_stOsdEventData.ullCacheFlag |= ((UINT64)BIT_0 << (x)))
#define GET_EVENT_CACHABLE_FLAG(x)           ((s_stOsdEventData.ullCacheFlag >> (x)) & (UINT64)BIT_0)
#define CLEAR_EVENT_CACHABLE_FLAG(x)         (s_stOsdEventData.ullCacheFlag &= ~((UINT64)BIT_0 << (x)))
#define SET_EVENT_CACHABLE_FLAG_ALL()        (s_stOsdEventData.ullCacheFlag = 0xFFFFFFFFFFFFFFFF)
#define CLEAR_EVENT_CACHABLE_FLAG_ALL()      (s_stOsdEventData.ullCacheFlag = 0x0)

#define SET_EVENT_CACHABLE_ONCE_FLAG(x)           (s_stOsdEventData.ullCacheOnceFlag |= ((UINT64)BIT_0 << (x)))
#define GET_EVENT_CACHABLE_ONCE_FLAG(x)           ((s_stOsdEventData.ullCacheOnceFlag >> (x)) & (UINT64)BIT_0)
#define CLEAR_EVENT_CACHABLE_ONCE_FLAG(x)         (s_stOsdEventData.ullCacheOnceFlag &= ~((UINT64)BIT_0 << (x)))
#define SET_EVENT_CACHABLE_ONCE_FLAG_ALL()        (s_stOsdEventData.ullCacheOnceFlag = 0xFFFFFFFFFFFFFFFF)
#define CLEAR_EVENT_CACHABLE_ONCE_FLAG_ALL()      (s_stOsdEventData.ullCacheOnceFlag = 0x0)

#define SET_EVENT_FORCE_PROCESS_FLAG(x)           (s_stOsdEventData.ullForceProcessFlag |= ((UINT64)BIT_0 << (x)))
#define GET_EVENT_FORCE_PROCESS_FLAG(x)           ((s_stOsdEventData.ullForceProcessFlag >> (x)) & (UINT64)BIT_0)
#define CLEAR_EVENT_FORCE_PROCESS_FLAG(x)         (s_stOsdEventData.ullForceProcessFlag &= ~((UINT64)BIT_0 << (x)))
#define SET_EVENT_FORCE_PROCESS_FLAG_ALL()        (s_stOsdEventData.ullForceProcessFlag = 0xFFFFFFFFFFFFFFFF)
#define CLEAR_EVENT_FORCE_PROCESS_FLAG_ALL()      (s_stOsdEventData.ullForceProcessFlag = 0x0)

#define SET_EVENT_LOGOING_PROCESS_FLAG(x)          (s_stOsdEventData.ullLogoingProcessFlag |= ((UINT64)BIT_0 << (x)))
#define GET_EVENT_LOGOING_PROCESS_FLAG(x)          ((s_stOsdEventData.ullLogoingProcessFlag >> (x)) & (UINT64)BIT_0)
#define CLEAR_EVENT_LOGOING_PROCESS_FLAG(x)        (s_stOsdEventData.ullLogoingProcessFlag &= ~((UINT64)BIT_0 << (x)))
#define SET_EVENT_LOGOING_PROCESS_FLAG_ALL()       (s_stOsdEventData.ullLogoingProcessFlag = 0xFFFFFFFFFFFFFFFF)
#define CLEAR_EVENT_LOGOING_PROCESS_FLAG_ALL()     (s_stOsdEventData.ullLogoingProcessFlag = 0x0)

static const CHAR8* s_apcEventNameTbl[] =
{
    [OSD_EVENT_KEY_PRESS] =                     "EVENT_KEY_PRESS",
    [OSD_EVENT_KEY_HOLD] =                      "EVENT_KEY_HOLD",
    [OSD_EVENT_KEY_RELEASE] =                   "EVENT_KEY_RELEASE",
    [OSD_EVENT_KEY_DOUBLE_CLICK] =              "EVENT_KEY_DOUBLE_CLICK",
    [OSD_EVENT_IR_KEY] =                        "EVENT_IR_KEY",
    [OSD_EVENT_IR_REPEAT_KEY] =                 "EVENT_IR_REPEAT_KEY",
    [OSD_EVENT_SHOW_LOGO] =                     "EVENT_SHOW_LOGO",
    [OSD_EVENT_POWER_ON] =                      "EVENT_POWER_ON",
    [OSD_EVENT_POWER_OFF] =                     "EVENT_POWER_OFF",
    [OSD_EVENT_POWER_STANDBY] =                 "EVENT_POWER_STANDBY",
    [OSD_EVENT_LOCK] =                          "EVENT_LOCK",
    [OSD_EVENT_SIGNAL_READY] =                  "EVENT_SIGNAL_READY",
    [OSD_EVENT_SIGNAL_STATE_CHANGE] =           "EVENT_SIGNAL_STATE_CHANGE",
    [OSD_EVENT_SIGNAL_PARAM_CHANGE] =           "EVENT_SIGNAL_PARAM_CHANGE",
    [OSD_EVENT_SIGNAL_TIMING_NOT_SUPPORT] =     "EVENT_SIGNAL_TIMING_NOT_SUPPORT",
    [OSD_EVENT_SIGNAL_PLUG_IN] =                "EVENT_SIGNAL_PLUG_IN",
    [OSD_EVENT_SIGNAL_PLUG_OUT] =               "EVENT_SIGNAL_PLUG_OUT",
    [OSD_EVENT_SYNC] =                          "EVENT_SYNC",
    [OSD_EVENT_ANIMITION] =                     "EVENT_ANIMITION",
    [OSD_EVENT_MCCS] =                          "EVENT_MCCS",
    [OSD_EVENT_FACTORY_ENTER] =                 "EVENT_FACTORY_ENTER",
    [OSD_EVENT_FACTORY_EXIT] =                  "EVENT_FACTORY_EXIT",
    [OSD_EVENT_FACTORY_AGING_REFRESH] =         "EVENT_FACTORY_AGING_REFRESH",
    [OSD_EVENT_FACTORY_AGING_EXIT] =            "EVENT_FACTORY_AGING_EXIT",
    [OSD_EVENT_USB_OTA] =                       "EVENT_USB_OTA",
    [OSD_EVENT_HIDE_ALL] =                      "EVENT_HIDE_ALL",
    [OSD_EVENT_TEST] =                          "EVENT_TEST",
    [OSD_EVENT_CUSTOM1] =                       "EVENT_CUSTOM1",
    [OSD_EVENT_CUSTOM2] =                       "EVENT_CUSTOM2",
    [OSD_EVENT_CUSTOM3] =                       "EVENT_CUSTOM3",
    [OSD_EVENT_MAX] =                           "EVENT_NONE",
};

static const CHAR8* s_apcTimerEventNameTbl[] =
{
    "EVENT_TIMER_KEY_REPEAT",
    "EVENT_TIMER_KEY_HOLD",
    "EVENT_TIMER_AUTO_CLOSE",
    "EVENT_TIMER_AUTO_REFRESH",
    "EVENT_TIMER_LOGO_HIDE",
    "EVENT_TIMER_REMIND",
};

const CHAR8 *Hv_Mw_OsdGetEventName(OsdEventId enId)
{
    if (enId < OSD_EVENT_MAX)
    {
        return s_apcEventNameTbl[enId];
    }
    else if (((USHORT16)enId >= OSD_EVENT_TIMER_START) && ((USHORT16)enId < OSD_EVENT_TIMER_END))
    {
        return s_apcTimerEventNameTbl[(USHORT16)enId - OSD_EVENT_TIMER_START];
    }
    else
    {
        return s_apcEventNameTbl[OSD_EVENT_MAX];
    }
}

static const CHAR8* s_apcKeyNameTbl[] =
{
    [OSDEVT_KEY_UP] =           "KEY_UP",
    [OSDEVT_KEY_DOWN] =         "KEY_DOWN",
    [OSDEVT_KEY_LEFT] =         "KEY_LEFT",
    [OSDEVT_KEY_RIGHT] =        "KEY_RIGHT",
    [OSDEVT_KEY_ENTER] =        "KEY_ENTER",
    [OSDEVT_KEY_EXIT] =         "KEY_EXIT",
    [OSDEVT_KEY_POWER] =        "KEY_POWER",
    [OSDEVT_KEY_HOTKEY1] =      "KEY_HOTKEY1",
    [OSDEVT_KEY_HOTKEY2] =      "KEY_HOTKEY2",
    [OSDEVT_KEY_HOTKEY3] =      "KEY_HOTKEY3",
    [OSDEVT_KEY_CUSTOM1] =      "KEY_CUSTOM1",
    [OSDEVT_KEY_CUSTOM2] =      "KEY_CUSTOM2",
    [OSDEVT_KEY_CUSTOM3] =      "KEY_CUSTOM3",
    [OSDEVT_KEY_CUSTOM4] =      "KEY_CUSTOM4",
    [OSDEVT_KEY_CUSTOM5] =      "KEY_CUSTOM5",
    [OSDEVT_KEY_MAX] =          "KEY_NONE",
};

const CHAR8 *Hv_Mw_OsdGetKeyName(OsdEvtKeyValue enId)
{
    return enId < OSDEVT_KEY_MAX ? s_apcKeyNameTbl[enId] : s_apcKeyNameTbl[OSDEVT_KEY_MAX];
}

VOID Hv_Mw_OsdSetEventProp(USHORT16 usEventId, OsdEventProp enProp, BOOL bIsSet)
{
    USHORT16 usId = 0;

    if (usEventId < OSD_EVENT_MAX)
    {
        usId = usEventId;
    }
    else if ((usEventId >= OSD_EVENT_TIMER_START) && (usEventId < OSD_EVENT_TIMER_END))
    {
        usId = OSD_EVENT_MAX + (OSD_EVENT_TIMER_END - usEventId);
    }
    else
    {
        OSD_LOG_ERROR("Error usEventId = %d in SetEventProp", usEventId);
        return;
    }

    switch (enProp)
    {
        case OSDEVT_CACHABLE:
        {
            OSD_LOG_DEBUG("set %s cachable = %d", Hv_Mw_OsdGetEventName(usEventId), bIsSet);
            bIsSet ? SET_EVENT_CACHABLE_FLAG(usId) : CLEAR_EVENT_CACHABLE_FLAG(usId);
            break;
        }
        case OSDEVT_CACHABLE_ONCE:
        {
            OSD_LOG_DEBUG("set %s cachable once = %d", Hv_Mw_OsdGetEventName(usEventId), bIsSet);
            bIsSet ? SET_EVENT_CACHABLE_ONCE_FLAG(usId) : CLEAR_EVENT_CACHABLE_ONCE_FLAG(usId);
            break;
        }
        case OSDEVT_FORCE_PROCESS:
        {
            OSD_LOG_DEBUG("set %s force process = %d", Hv_Mw_OsdGetEventName(usEventId), bIsSet);
            bIsSet ? SET_EVENT_FORCE_PROCESS_FLAG(usId) : CLEAR_EVENT_FORCE_PROCESS_FLAG(usId);
            break;
        }
        case OSDEVT_LOGOING_PROCESS:
        {
            OSD_LOG_DEBUG("set %s logoing process = %d", Hv_Mw_OsdGetEventName(usEventId), bIsSet);
            bIsSet ? SET_EVENT_LOGOING_PROCESS_FLAG(usId) : CLEAR_EVENT_LOGOING_PROCESS_FLAG(usId);
            break;
        }
        default:
        {
            break;
        }
    }
}

BOOL Hv_Mw_OsdGetEventProp(USHORT16 usEventId, OsdEventProp enProp)
{
    USHORT16 usId = 0;

    if (usEventId < OSD_EVENT_MAX)
    {
        usId = usEventId;
    }
    else if ((usEventId >= OSD_EVENT_TIMER_START) && (usEventId < OSD_EVENT_TIMER_END))
    {
        usId = OSD_EVENT_MAX + (OSD_EVENT_TIMER_END - usEventId);
    }
    else
    {
        OSD_LOG_ERROR("Error usEventId = %d in SetEventProp", usEventId);
        return HV_FALSE;
    }

    switch (enProp)
    {
        case OSDEVT_CACHABLE:
        {
            return GET_EVENT_CACHABLE_FLAG(usId);
        }
        case OSDEVT_CACHABLE_ONCE:
        {
            return GET_EVENT_CACHABLE_ONCE_FLAG(usId);
        }
        case OSDEVT_FORCE_PROCESS:
        {
            return GET_EVENT_FORCE_PROCESS_FLAG(usId);
        }
        case OSDEVT_LOGOING_PROCESS:
        {
            return GET_EVENT_LOGOING_PROCESS_FLAG(usId);
        }
        default:
        {
            return HV_FALSE;
        }
    }
}

VOID Hv_Mw_OsdSetKeyState(OsdEvtKeyValue enKey, OsdKeyState enState, BOOL bIsSet)
{
    switch (enState)
    {
        case KEY_STATE_HOLDABLE:
        {
            OSD_LOG_DEBUG("set %s holdable = %d", Hv_Mw_OsdGetKeyName(enKey), bIsSet);
            bIsSet ? SET_HOLDABLE_FLAG(enKey) : CLEAR_HOLDABLE_FLAG(enKey);
            break;
        }
        case KEY_STATE_REPEATABLE:
        {
            OSD_LOG_DEBUG("set %s repeatable = %d", Hv_Mw_OsdGetKeyName(enKey), bIsSet);
            bIsSet ? SET_REPEATABLE_FLAG(enKey) : CLEAR_REPEATABLE_FLAG(enKey);
            break;
        }
        case KEY_STATE_DISABLE:
        {
            OSD_LOG_DEBUG("set %s disable = %d", Hv_Mw_OsdGetKeyName(enKey), bIsSet);
            bIsSet ? SET_DISABLE_STATE_FLAG(enKey) : CLEAR_DISABLE_STATE_FLAG(enKey);
            break;
        }
        default:
        {
            break;
        }
    }
}

VOID Hv_Mw_OsdSetAllKeyEnable(BOOL bEnable)
{
    if (bEnable)
    {
        OSD_LOG_INFO("Enable all key.");
        s_stOsdEventData.usKeyDisableStateFlag = 0x0;
    }
    else
    {
        OSD_LOG_INFO("Disable all key.");
        s_stOsdEventData.usKeyDisableStateFlag = 0xffff;
    }
}

OsdEvtKeyValue Hv_Mw_OsdGetKeyValue(VOID)
{
    return s_stOsdEventData.enKeyValue;
}

OsdEvtKeyValue Hv_Mw_OsdGetHoldKey(VOID)
{
    return s_stOsdEventData.enHoldKeyValue;
}

BOOL Hv_Mw_OsdGetKeyIsRepeating(OsdEvtKeyValue enKey)
{
    return GET_REPEAT_STATE_FLAG(enKey);
}

VOID Hv_Mw_OsdSetKeyRepeatPeriod(UINT32 uiPeriodMS)
{
    s_stOsdEventData.uiKeyRepeatPeriodMs = uiPeriodMS;
}

VOID Hv_Mw_OsdSetKeyHoldPeriod(UINT32 uiHoldTimeMS)
{
    for (USHORT16 usKey = 0; usKey < OSDEVT_KEY_MAX; usKey++)
    {
        s_stOsdEventData.uiKeyHoldPeriodMs[usKey] = uiHoldTimeMS;
    }
}

VOID Hv_Mw_OsdSetOneKeyHoldPeriod(OsdEvtKeyValue enKey, UINT32 uiHoldTimeMS)
{
    HV_ASSERT_TRUE_VOID(enKey < OSDEVT_KEY_MAX);
    s_stOsdEventData.uiKeyHoldPeriodMs[enKey] = uiHoldTimeMS;
}

static VOID Hv_Mw_OsdCreateRepeatTimer(VOID)
{
#ifdef OSD_USE_HW_TIMER
    HwTimerParams stParam = { 0 };

    stParam.name = "OsdKeyRepeatTimer";
    stParam.periodMs = (UINT64)OSD_DEFAULT_KEY_REPEAT_PERIOD_MS;
    stParam.callbackFn = NULL;
    stParam.timerEvent = OSD_EVENT_TIMER_KEY_REPEAT;
    stParam.next = NULL;

    s_stOsdEventData.pstKeyRepeatTimer = Hv_Common_HwTimer_Create(&stParam);
#else
    HV_TIMER_INIT_PARAMS stParam = \
        {"OsdKeyRepeatTimer", (UINT32)OSD_DEFAULT_KEY_REPEAT_PERIOD_MS, HV_FALSE, NULL, Hv_Common_Timer_DispatchEvent, OSD_EVENT_TIMER_KEY_REPEAT};
    s_stOsdEventData.pstKeyRepeatTimer = Hv_Vos_Timer_Create(&stParam);
#endif
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.pstKeyRepeatTimer);
}

static VOID Hv_Mw_OsdCreateHoldTimer(VOID)
{
#ifdef OSD_USE_HW_TIMER
    HwTimerParams stParam = { 0 };

    stParam.name = "OsdKeyHoldTimer";
    stParam.periodMs = (UINT64)OSD_DEFAULT_KEY_HOLD_TIME_MS;
    stParam.callbackFn = NULL;
    stParam.timerEvent = OSD_EVENT_TIMER_KEY_HOLD;
    stParam.next = NULL;

    s_stOsdEventData.pstKeyHoldTimer = Hv_Common_HwTimer_Create(&stParam);
#else
    HV_TIMER_INIT_PARAMS stParam = \
        {"OsdKeyHoldTimer", OSD_DEFAULT_KEY_HOLD_TIME_MS, HV_FALSE, NULL, Hv_Common_Timer_DispatchEvent, OSD_EVENT_TIMER_KEY_HOLD};
    s_stOsdEventData.pstKeyHoldTimer = Hv_Vos_Timer_Create(&stParam);
#endif
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.pstKeyHoldTimer);
}

static VOID Hv_Mw_OsdDeleteRepeatTimer(VOID)
{
    if (s_stOsdEventData.pstKeyRepeatTimer)
    {
#ifdef OSD_USE_HW_TIMER
        Hv_Common_HwTimer_Delete(s_stOsdEventData.pstKeyRepeatTimer);
#else
        Hv_Vos_Timer_Delete(s_stOsdEventData.pstKeyRepeatTimer);
#endif
        s_stOsdEventData.pstKeyRepeatTimer = NULL;
    }
}

static VOID Hv_Mw_OsdDeleteHoldTimer(VOID)
{
    if (s_stOsdEventData.pstKeyHoldTimer)
    {
#ifdef OSD_USE_HW_TIMER
        Hv_Common_HwTimer_Delete(s_stOsdEventData.pstKeyHoldTimer);
#else
        Hv_Vos_Timer_Delete(s_stOsdEventData.pstKeyHoldTimer);
#endif
        s_stOsdEventData.pstKeyHoldTimer = NULL;
    }
}

static VOID Hv_Mw_OsdStartKeyRepeatTimer(VOID)
{
    if (s_stOsdEventData.pstKeyRepeatTimer)
    {
#ifdef OSD_USE_HW_TIMER
        s_stOsdEventData.pstKeyRepeatTimer->periodMs = (UINT64)(s_stOsdEventData.uiKeyRepeatPeriodMs);
        Hv_Common_HwTimer_Start(s_stOsdEventData.pstKeyRepeatTimer);
#else
        Hv_Vos_Timer_Rstart(s_stOsdEventData.pstKeyRepeatTimer, s_stOsdEventData.uiKeyRepeatPeriodMs);
#endif
    }
}

static VOID Hv_Mw_OsdStartKeyHoldTimer(OsdEvtKeyValue enKey)
{
    if (s_stOsdEventData.pstKeyHoldTimer)
    {
#ifdef OSD_USE_HW_TIMER
        s_stOsdEventData.pstKeyHoldTimer->periodMs = (UINT64)(s_stOsdEventData.uiKeyHoldPeriodMs[enKey]);
        Hv_Common_HwTimer_Start(s_stOsdEventData.pstKeyHoldTimer);
#else
        Hv_Vos_Timer_Rstart(s_stOsdEventData.pstKeyHoldTimer, s_stOsdEventData.uiKeyHoldPeriodMs[enKey]);
#endif
    }
}

static OsdEventId Hv_Mw_OsdKeyEventProc(OsdEvent *pstEventMsg)
{
    HV_ASSERT_VALID_PTR_RET(pstEventMsg, OSD_EVENT_MAX);
    OsdEventId enEvent = OSD_EVENT_MAX;
    OsdEvtKeyValue enKey = OSDEVT_KEY_NONE;

    enKey = pstEventMsg->usValue;

    if (enKey == OSDEVT_KEY_NONE)
    {
        s_stOsdEventData.enKeyValue = OSDEVT_KEY_NONE;
        return enEvent;
    }
    else if (GET_DISABLE_STATE_FLAG(enKey))
    {
        /* 按键被禁用 */
        OSD_LOG_INFO("%s disabled", Hv_Mw_OsdGetKeyName(enKey));
        s_stOsdEventData.enKeyValue = OSDEVT_KEY_NONE;
        return enEvent;
    }

    /* 按键按下 */
    if (pstEventMsg->usEventId == OSD_EVENT_KEY_PRESS)
    {
#ifdef HV_SCALER_DEBUG_VERSION
        if (!Hv_Mw_OsdIsMonkeyRunning())
#endif
        {
            OSD_LOG_INFO("%s Press", Hv_Mw_OsdGetKeyName(enKey));
        }

        if (KEY_IS_REPEATING())
        {
            OSD_LOG_DEBUG("Stop repeat key timer");
#ifdef OSD_USE_HW_TIMER
            Hv_Common_HwTimer_Stop(s_stOsdEventData.pstKeyRepeatTimer);
#else
            Hv_Vos_Timer_Stop(s_stOsdEventData.pstKeyRepeatTimer);
#endif
            s_stOsdEventData.enHoldKeyValue = OSDEVT_KEY_NONE;
            CLEAR_REPEAT_STATE_FLAG_ALL();
        }

        if (KEY_IS_HOLDING())
        {
            OSD_LOG_DEBUG("Stop hold key timer");
#ifdef OSD_USE_HW_TIMER
            Hv_Common_HwTimer_Stop(s_stOsdEventData.pstKeyHoldTimer);
#else
            Hv_Vos_Timer_Stop(s_stOsdEventData.pstKeyHoldTimer);
#endif
            s_stOsdEventData.enHoldKeyValue = OSDEVT_KEY_NONE;
            CLEAR_HOLD_STATE_FLAG_ALL();
        }
        s_stOsdEventData.enKeyValue = enKey;
        enEvent = OSD_EVENT_KEY_PRESS;
    }
    /* 按键长按 */
    else if (pstEventMsg->usEventId == OSD_EVENT_KEY_HOLD)
    {
        s_stOsdEventData.enKeyValue = OSDEVT_KEY_NONE;

        if (GET_REPEATABLE_FLAG(enKey) && (!GET_REPEAT_STATE_FLAG(enKey)))
        {
            OSD_LOG_INFO("%s repeating", Hv_Mw_OsdGetKeyName(enKey));
            SET_REPEAT_STATE_FLAG(enKey);
            Hv_Mw_OsdStartKeyRepeatTimer();
            s_stOsdEventData.enHoldKeyValue = enKey;
            s_stOsdEventData.enKeyValue = enKey;
            enEvent = OSD_EVENT_KEY_PRESS;
        }

        if (GET_HOLDABLE_FLAG(enKey) && (!GET_HOLD_STATE_FLAG(enKey)))
        {
            OSD_LOG_INFO("%s hold start", Hv_Mw_OsdGetKeyName(enKey));
            SET_HOLD_STATE_FLAG(enKey);
            Hv_Mw_OsdStartKeyHoldTimer(enKey);
            s_stOsdEventData.enHoldKeyValue = enKey;
        }
    }
    /* 按键释放 */
    else if (pstEventMsg->usEventId == OSD_EVENT_KEY_RELEASE)
    {
        OSD_LOG_INFO("%s Release", Hv_Mw_OsdGetKeyName(enKey));
        if (GET_REPEAT_STATE_FLAG(enKey))
        {
            OSD_LOG_DEBUG("%s repeat stop", Hv_Mw_OsdGetKeyName(enKey));
#ifdef OSD_USE_HW_TIMER
            Hv_Common_HwTimer_Stop(s_stOsdEventData.pstKeyRepeatTimer);
#else
            Hv_Vos_Timer_Stop(s_stOsdEventData.pstKeyRepeatTimer);
#endif
            CLEAR_REPEAT_STATE_FLAG(enKey);
            s_stOsdEventData.enHoldKeyValue = OSDEVT_KEY_NONE;
        }

        if (GET_HOLD_STATE_FLAG(enKey))
        {
            OSD_LOG_DEBUG("%s hold stop", Hv_Mw_OsdGetKeyName(enKey));
#ifdef OSD_USE_HW_TIMER
            Hv_Common_HwTimer_Stop(s_stOsdEventData.pstKeyHoldTimer);
#else
            Hv_Vos_Timer_Stop(s_stOsdEventData.pstKeyHoldTimer);
#endif
            CLEAR_HOLD_STATE_FLAG(enKey);
            s_stOsdEventData.enHoldKeyValue = OSDEVT_KEY_NONE;

            enEvent = OSD_EVENT_KEY_RELEASE;
        }
        s_stOsdEventData.enKeyValue = enKey;
    }
    else
    {
        s_stOsdEventData.enKeyValue = OSDEVT_KEY_NONE;
    }

    return enEvent;
}

VOID Hv_Mw_OsdEventProc(OsdEvent *pstEventMsg)
{
    HV_ASSERT_VALID_PTR_VOID(pstEventMsg);
    OSD_LOG_DEBUG("OSD Get Event: %s, Value = %d", Hv_Mw_OsdGetEventName(pstEventMsg->usEventId), pstEventMsg->usValue);
    /* key事件 */
    if (pstEventMsg->usEventId < OSD_EVENT_KEY_MAX)
    {
        pstEventMsg->usEventId = Hv_Mw_OsdKeyEventProc(pstEventMsg);
    }
    /* 连续重复按键 */
    else if (pstEventMsg->usEventId == OSD_EVENT_TIMER_KEY_REPEAT)
    {
        if ((s_stOsdEventData.enHoldKeyValue != OSDEVT_KEY_NONE))
        {
            if ((!GET_DISABLE_STATE_FLAG(s_stOsdEventData.enHoldKeyValue)) && GET_REPEATABLE_FLAG(s_stOsdEventData.enHoldKeyValue))
            {
                s_stOsdEventData.enKeyValue = s_stOsdEventData.enHoldKeyValue;
                OSD_LOG_DEBUG("%s REPEAT", Hv_Mw_OsdGetKeyName(s_stOsdEventData.enKeyValue));
                Hv_Mw_OsdStartKeyRepeatTimer();
                pstEventMsg->usEventId = OSD_EVENT_KEY_PRESS;
                return;
            }
            else
            {
                CLEAR_REPEAT_STATE_FLAG(s_stOsdEventData.enHoldKeyValue);
                s_stOsdEventData.enKeyValue = OSDEVT_KEY_NONE;
                s_stOsdEventData.enHoldKeyValue = OSDEVT_KEY_NONE;
            }
        }
        pstEventMsg->usEventId = OSD_EVENT_MAX;
    }
    else
    {
        /* 其他事件直接返回 */
#ifdef HV_SCALER_DEBUG_VERSION
        if (pstEventMsg->usEventId == OSD_EVENT_SIGNAL_STATE_CHANGE)
        {
            s_stOsdEventData.ullSyncTick = Hv_Vos_GetTick();
        }
#endif
    }
}

VOID Hv_Mw_OsdStartAutoCloseTimerMs(UCHAR8 ucSceneId, UINT32 uiMs)
{
#ifdef HV_SCALER_DEBUG_VERSION
    if (s_stOsdEventData.bDisableAutoClose)
    {
        OSD_LOG_WARN("Auto close timer disabled");
        return;
    }
#endif
    HV_ASSERT_TRUE_VOID(ucSceneId < SCENE_ID_MAX);
    OSD_LOG_DEBUG("AutoCloseTimer-%s auto close timeout = %dms start", SCENE_NAME(ucSceneId), uiMs);
#ifdef OSD_USE_HW_TIMER
    if (s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId])
    {
        OSD_LOG_DEBUG("AutoCloseTimer-%s already created", SCENE_NAME(ucSceneId));
        Hv_Common_HwTimer_Stop(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);
        s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]->periodMs = (UINT64)uiMs;
        Hv_Common_HwTimer_Start(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);
        return;
    }

    HwTimerParams stParam = { 0 };
    stParam.name = "OsdAutoCloseTimer";
    stParam.periodMs = (UINT64)uiMs;
    stParam.callbackFn = NULL;
    stParam.timerEvent = OSD_EVENT_TIMER_AUTO_CLOSE;
    stParam.param = ucSceneId;
    stParam.next = NULL;
    s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId] = Hv_Common_HwTimer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);

    Hv_Common_HwTimer_Start(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);
#else
    if (s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId])
    {
        OSD_LOG_DEBUG("AutoCloseTimer-%s already created", SCENE_NAME(ucSceneId));
        Hv_Vos_Timer_Rstart(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId], (UINT32)uiMs);
        return;
    }

    HV_TIMER_INIT_PARAMS stParam = \
        {"OsdAutoCloseTimer", (UINT32)uiMs, HV_FALSE, (VOID *)((UINT32)ucSceneId), Hv_Common_Timer_DispatchEvent, OSD_EVENT_TIMER_AUTO_CLOSE};
    s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId] = Hv_Vos_Timer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);

    Hv_Vos_Timer_Start(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);
#endif
}

VOID Hv_Mw_OsdStartAutoCloseTimer(UCHAR8 ucSceneId, USHORT16 usSecond)
{
    Hv_Mw_OsdStartAutoCloseTimerMs(ucSceneId, (UINT32)usSecond * 1000);
}

VOID Hv_Mw_OsdStopAutoCloseTimer(UCHAR8 ucSceneId)
{
    HV_ASSERT_TRUE_VOID(ucSceneId < SCENE_ID_MAX);

    if (s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId])
    {
        OSD_LOG_DEBUG("OsdAutoCloseTimer-%s stop", SCENE_NAME(ucSceneId));
#ifdef OSD_USE_HW_TIMER
        Hv_Common_HwTimer_Stop(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);
#else
        Hv_Vos_Timer_Stop(s_stOsdEventData.apstAutoCloseTimerArray[ucSceneId]);
#endif
    }
}

VOID Hv_Mw_OsdStartAutoRefreshTimer(UCHAR8 ucSceneId, UINT32 uiTimeoutMs)
{
    HV_ASSERT_TRUE_VOID(ucSceneId < SCENE_ID_MAX);
#ifdef OSD_USE_HW_TIMER
    HwTimerParams stParam = { 0 };

    OSD_LOG_DEBUG("OsdAutoRefreshTimer-%s auto refresh timeout = %dms start", SCENE_NAME(ucSceneId), uiTimeoutMs);
    if (s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId])
    {
        OSD_LOG_DEBUG("OsdAutoRefreshTimer-%s already created", SCENE_NAME(ucSceneId));
        Hv_Common_HwTimer_Stop(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);
        s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]->periodMs = (UINT64)uiTimeoutMs;
        Hv_Common_HwTimer_Start(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);
        return;
    }

    stParam.name = "OsdAutoRefreshTimer";
    stParam.periodMs = (UINT64)uiTimeoutMs;
    stParam.callbackFn = NULL;
    stParam.timerEvent = OSD_EVENT_TIMER_AUTO_REFRESH;
    stParam.param = ucSceneId;
    stParam.next = NULL;
    s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId] = Hv_Common_HwTimer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);

    Hv_Common_HwTimer_Start(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);
#else
    if (s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId])
    {
        OSD_LOG_DEBUG("OsdAutoRefreshTimer-%s already created", SCENE_NAME(ucSceneId));
        Hv_Vos_Timer_Rstart(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId], uiTimeoutMs);
        return;
    }

    HV_TIMER_INIT_PARAMS stParam = \
        {"OsdAutoRefreshTimer", uiTimeoutMs, HV_FALSE, (VOID *)((UINT32)ucSceneId), Hv_Common_Timer_DispatchEvent, OSD_EVENT_TIMER_AUTO_REFRESH};
    s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId] = Hv_Vos_Timer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);

    Hv_Vos_Timer_Start(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);
#endif
}

VOID Hv_Mw_OsdStopAutoRefreshTimer(UCHAR8 ucSceneId)
{
    HV_ASSERT_TRUE_VOID(ucSceneId < SCENE_ID_MAX);

    if (s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId])
    {
        OSD_LOG_DEBUG("OsdAutoRefreshTimer-%s stop", SCENE_NAME(ucSceneId));
#ifdef OSD_USE_HW_TIMER
        Hv_Common_HwTimer_Stop(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);
#else
        Hv_Vos_Timer_Stop(s_stOsdEventData.apstAutoRefreshTimerArray[ucSceneId]);
#endif
    }
}

VOID Hv_Mw_OsdStartLogoTimerMs(UINT32 uiMs)
{
#ifdef HV_SCALER_DEBUG_VERSION
    if (s_stOsdEventData.bDisableAutoClose)
    {
        OSD_LOG_WARN("Auto close timer disabled");
        return;
    }
#endif
#ifdef OSD_USE_HW_TIMER
    if (s_stOsdEventData.pstLogoTimer)
    {
        OSD_LOG_DEBUG("Logo HwTimer already created, pstLogoTimer = 0x%x, start timeout = %dms",
                     s_stOsdEventData.pstLogoTimer, uiMs);
        Hv_Common_HwTimer_Stop(s_stOsdEventData.pstLogoTimer);
        s_stOsdEventData.pstLogoTimer->periodMs = (UINT64)uiMs;
        Hv_Common_HwTimer_Start(s_stOsdEventData.pstLogoTimer);
        return;
    }

    HwTimerParams stParam = { 0 };
    stParam.name = "OsdLogoTimer";
    stParam.periodMs = (UINT64)uiMs;
    stParam.callbackFn = NULL;
    stParam.timerEvent = OSD_EVENT_TIMER_LOGO_HIDE;
    stParam.next = NULL;
    OSD_LOG_DEBUG("Create logo HwTimer, EventId = %d", OSD_EVENT_TIMER_LOGO_HIDE);
    s_stOsdEventData.pstLogoTimer = Hv_Common_HwTimer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.pstLogoTimer);

    OSD_LOG_DEBUG("Start logo HwTimer, timeout = %dms", uiMs);
    Hv_Common_HwTimer_Start(s_stOsdEventData.pstLogoTimer);
#else
    if (s_stOsdEventData.pstLogoTimer)
    {
        OSD_LOG_DEBUG("Logo timer already created, pstLogoTimer = 0x%x, start timeout = %dms",
                     s_stOsdEventData.pstLogoTimer, uiMs);
        Hv_Vos_Timer_Rstart(s_stOsdEventData.pstLogoTimer, (UINT32)uiMs);
        return;
    }

    HV_TIMER_INIT_PARAMS stParam = \
        {"OsdLogoTimer", (UINT32)uiMs, HV_FALSE, NULL, Hv_Common_Timer_DispatchEvent, OSD_EVENT_TIMER_LOGO_HIDE};
    OSD_LOG_DEBUG("Create logo Timer, EventId = %d", OSD_EVENT_TIMER_LOGO_HIDE);
    s_stOsdEventData.pstLogoTimer = Hv_Vos_Timer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.pstLogoTimer);

    OSD_LOG_DEBUG("Start logo Timer, timeout = %dms", uiMs);
    Hv_Vos_Timer_Start(s_stOsdEventData.pstLogoTimer);
#endif
}

VOID Hv_Mw_OsdStartLogoTimer(USHORT16 usSecond)
{
    Hv_Mw_OsdStartLogoTimerMs((UINT32)usSecond * 1000);
}

VOID Hv_Mw_OsdStopLogoTimer(VOID)
{
    if (s_stOsdEventData.pstLogoTimer)
    {
#ifdef OSD_USE_HW_TIMER
        OSD_LOG_DEBUG("Logo HwTimer stop");
        Hv_Common_HwTimer_Stop(s_stOsdEventData.pstLogoTimer);
#else
        OSD_LOG_DEBUG("Logo Timer stop");
        Hv_Vos_Timer_Stop(s_stOsdEventData.pstLogoTimer);
#endif
    }
}

VOID Hv_Mw_OsdStartReminderTimer(UCHAR8 ucRemindId, UINT32 uiTimeoutMs, BOOL bRepeat)
{
    HV_ASSERT_TRUE_VOID(ucRemindId < OSD_REMINDER_NUM);

    OSD_LOG_DEBUG("OsdReminderTimer-%d timeout = %dms start", ucRemindId, uiTimeoutMs);

    if (s_stOsdEventData.apstReminderTimerArray[ucRemindId])
    {
        OSD_LOG_DEBUG("OsdReminderTimer-%d already created", ucRemindId);
        Hv_Vos_Timer_Rstart(s_stOsdEventData.apstReminderTimerArray[ucRemindId], uiTimeoutMs);
        return;
    }

    HV_TIMER_INIT_PARAMS stParam = \
        {"OsdReminderTimer", uiTimeoutMs, bRepeat, (VOID *)((UINT32)ucRemindId), Hv_Common_Timer_DispatchEvent, OSD_EVENT_TIMER_REMIND};
    s_stOsdEventData.apstReminderTimerArray[ucRemindId] = Hv_Vos_Timer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.apstReminderTimerArray[ucRemindId]);

    Hv_Vos_Timer_Start(s_stOsdEventData.apstReminderTimerArray[ucRemindId]);
}

VOID Hv_Mw_OsdStopReminderTimer(UCHAR8 ucRemindId)
{
    HV_ASSERT_TRUE_VOID(ucRemindId < OSD_REMINDER_NUM);

    if (s_stOsdEventData.apstReminderTimerArray[ucRemindId])
    {
        OSD_LOG_DEBUG("OsdReminderTimer-%d stop", ucRemindId);

        Hv_Vos_Timer_Stop(s_stOsdEventData.apstReminderTimerArray[ucRemindId]);
    }
}

#ifdef HV_SCALER_DEBUG_VERSION
VOID Hv_Mw_OsdSetAutoCloseTimerEnable(BOOL bEnable)
{
    s_stOsdEventData.bDisableAutoClose = !bEnable;
    OSD_LOG_INFO("Set bDisableAutoClose = %d", s_stOsdEventData.bDisableAutoClose);
}

static VOID OsdMonkeyTest(HvCommonHwTimer* pstTimer)
{
    UINT64 ullRandSeed = Hv_Common_Db_GetUserDataDBRegionPtr()->usCheckCrc + s_stOsdEventData.ullSyncTick;
    OSD_LOG_VERBOSE("ullRandSeed = 0x%llx", ullRandSeed);
    USHORT16 usValue = (ullRandSeed + rand()) % 8;
    if ((usValue == 0) || (usValue == 1))
    {
        usValue = OSDEVT_KEY_UP;
    }
    else if ((usValue == 2) || (usValue == 3))
    {
        usValue = OSDEVT_KEY_DOWN;
    }
    else if (usValue == 4)
    {
        usValue = OSDEVT_KEY_EXIT;
    }
    else
    {
        usValue = OSDEVT_KEY_ENTER;
    }

    HV_VOS_QUEUE_S* pOsdQueue = Hv_Mw_System_GetOsdQueue();
    HV_ASSERT_VALID_PTR_VOID(pOsdQueue);
    OsdEvent stOsdEvent = { 0 };
    HV_MEMSET(&stOsdEvent, 0, sizeof(OsdEvent));
    stOsdEvent.usEventId = OSD_EVENT_KEY_PRESS;
    stOsdEvent.usValue = usValue;
    Hv_Vos_QueueSend(pOsdQueue, &stOsdEvent);

    pstTimer->periodMs = ((ullRandSeed + rand()) % 3 + 1) * 100;
    Hv_Common_HwTimer_Start(pstTimer);
}

BOOL Hv_Mw_OsdIsMonkeyRunning(VOID)
{
    return s_stOsdEventData.bIsTesting;
}

VOID Hv_Mw_OsdMonkeyTest(BOOL bStart)
{
    if (bStart)
    {
        OSD_LOG_INFO("Osd monkey test start!");
        if (NULL == s_stOsdEventData.pstOsdTestTimer)
        {
            HwTimerParams stParam = { 0 };
            stParam.name = "OsdTestTimer";
            stParam.periodMs = 500;
            stParam.callbackFn = OsdMonkeyTest;
            s_stOsdEventData.pstOsdTestTimer = Hv_Common_HwTimer_Create(&stParam);
            HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.pstOsdTestTimer);
        }
        else
        {
            Hv_Common_HwTimer_Stop(s_stOsdEventData.pstOsdTestTimer);
            s_stOsdEventData.pstOsdTestTimer->periodMs = 500;
        }
        Hv_Common_HwTimer_Start(s_stOsdEventData.pstOsdTestTimer);
        s_stOsdEventData.bIsTesting = HV_TRUE;
    }
    else
    {
        OSD_LOG_INFO("Osd monkey test stop!");
        if (NULL != s_stOsdEventData.pstOsdTestTimer)
        {
            Hv_Common_HwTimer_Stop(s_stOsdEventData.pstOsdTestTimer);
        }
        s_stOsdEventData.bIsTesting = HV_FALSE;
    }
}

VOID Hv_Mw_OsdStartAutoTestTimer(UINT32 uiTimeoutMs)
{
    OSD_LOG_DEBUG("OsdAutoTestTimer refresh timeout = %dms start", uiTimeoutMs);
#ifdef OSD_USE_HW_TIMER
    HwTimerParams stParam = { 0 };
    if (s_stOsdEventData.pstOsdAutoTestTimer)
    {
        OSD_LOG_DEBUG("OsdAutoTestTimer already created");
        Hv_Common_HwTimer_Stop(s_stOsdEventData.pstOsdAutoTestTimer);
        s_stOsdEventData.pstOsdAutoTestTimer->periodMs = (UINT64)uiTimeoutMs;
        Hv_Common_HwTimer_Start(s_stOsdEventData.pstOsdAutoTestTimer);
        return;
    }

    stParam.name = "OsdAutoTestTimer";
    stParam.periodMs = (UINT64)uiTimeoutMs;
    stParam.callbackFn = NULL;
    stParam.timerEvent = OSD_EVENT_TIMER_AUTO_TEST;
    //stParam.param = NULL;
    stParam.next = NULL;
    s_stOsdEventData.pstOsdAutoTestTimer = Hv_Common_HwTimer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.pstOsdAutoTestTimer);

    Hv_Common_HwTimer_Start(s_stOsdEventData.pstOsdAutoTestTimer);
#else
    if (s_stOsdEventData.pstOsdAutoTestTimer)
    {
        OSD_LOG_DEBUG("OsdAutoTestTimer already created");
        Hv_Vos_Timer_Rstart(s_stOsdEventData.pstOsdAutoTestTimer, uiTimeoutMs);
        return;
    }

    HV_TIMER_INIT_PARAMS stParam = \
        {"OsdAutoTestTimer", uiTimeoutMs, HV_FALSE, NULL, Hv_Common_Timer_DispatchEvent, OSD_EVENT_TIMER_AUTO_TEST};
    s_stOsdEventData.pstOsdAutoTestTimer = Hv_Vos_Timer_Create(&stParam);
    HV_ASSERT_VALID_PTR_VOID(s_stOsdEventData.pstOsdAutoTestTimer);

    Hv_Vos_Timer_Start(s_stOsdEventData.pstOsdAutoTestTimer);
    OSD_LOG_INFO("OsdAutoTestTimer created and start");
#endif
    s_stOsdEventData.bIsTesting = HV_TRUE;
}

VOID Hv_Mw_OsdStopAutoTestTimer(VOID)
{
    OSD_LOG_DEBUG("Osd auto test stop!");
    if (s_stOsdEventData.pstOsdAutoTestTimer)
    {
#ifdef OSD_USE_HW_TIMER
        OSD_LOG_DEBUG("Logo HwTimer stop");
        Hv_Common_HwTimer_Stop(s_stOsdEventData.pstOsdAutoTestTimer);
#else
        OSD_LOG_DEBUG("Logo Timer stop");
        Hv_Vos_Timer_Stop(s_stOsdEventData.pstOsdAutoTestTimer);
#endif
    }
    s_stOsdEventData.bIsTesting = HV_FALSE;
}
#endif

VOID Hv_Mw_OsdEventInit(VOID)
{
    s_stOsdEventData.enKeyValue = OSDEVT_KEY_NONE;
    s_stOsdEventData.enHoldKeyValue = OSDEVT_KEY_NONE;
    Hv_Mw_OsdSetKeyHoldPeriod(OSD_DEFAULT_KEY_HOLD_TIME_MS);
    s_stOsdEventData.uiKeyRepeatPeriodMs = OSD_DEFAULT_KEY_REPEAT_PERIOD_MS;

    SET_EVENT_CACHABLE_FLAG_ALL();

    CLEAR_EVENT_CACHABLE_ONCE_FLAG_ALL();

    CLEAR_EVENT_FORCE_PROCESS_FLAG_ALL();

    CLEAR_EVENT_LOGOING_PROCESS_FLAG_ALL();
    Hv_Mw_OsdSetEventProp(OSD_EVENT_SHOW_LOGO, OSDEVT_LOGOING_PROCESS, HV_TRUE);
    Hv_Mw_OsdSetEventProp(OSD_EVENT_TIMER_LOGO_HIDE, OSDEVT_LOGOING_PROCESS, HV_TRUE);
    Hv_Mw_OsdSetEventProp(OSD_EVENT_POWER_ON, OSDEVT_LOGOING_PROCESS, HV_TRUE);
    Hv_Mw_OsdSetEventProp(OSD_EVENT_LOCK, OSDEVT_LOGOING_PROCESS, HV_TRUE);

    /* 清除所有按键重复，长按标志 */
    CLEAR_REPEATABLE_FLAG_ALL();
    CLEAR_HOLDABLE_FLAG_ALL();

    /* 清除所有按键重复，长按状态标志 */
    CLEAR_REPEAT_STATE_FLAG_ALL();
    CLEAR_HOLD_STATE_FLAG_ALL();

    /* 禁用所有按键 */
    Hv_Mw_OsdSetAllKeyEnable(HV_FALSE);

    /* 创建按键重复，长按timer */
    Hv_Mw_OsdCreateRepeatTimer();
    Hv_Mw_OsdCreateHoldTimer();

    /* 清除菜单自动关闭timer */
    HV_MEMSET(s_stOsdEventData.apstAutoCloseTimerArray, 0, sizeof(s_stOsdEventData.apstAutoCloseTimerArray));

    /* 清除菜单自动刷新timer */
    HV_MEMSET(s_stOsdEventData.apstAutoRefreshTimerArray, 0, sizeof(s_stOsdEventData.apstAutoRefreshTimerArray));

    /* 清除定时提醒timer */
    HV_MEMSET(s_stOsdEventData.apstReminderTimerArray, 0, sizeof(s_stOsdEventData.apstReminderTimerArray));

    s_stOsdEventData.pstLogoTimer = NULL;

#ifdef HV_SCALER_DEBUG_VERSION
    s_stOsdEventData.pstOsdTestTimer = NULL;
    s_stOsdEventData.bIsTesting = HV_FALSE;
    s_stOsdEventData.ullSyncTick = 0;
    s_stOsdEventData.bDisableAutoClose = HV_FALSE;
#endif
}

VOID Hv_Mw_OsdEventDeinit(VOID)
{
    /* 删除按键重复，长按timer */
    Hv_Mw_OsdDeleteRepeatTimer();
    Hv_Mw_OsdDeleteHoldTimer();
}
