/*
**
** Copyright 2014, Samsung Electronics Co. LTD
**
** 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.
*/

/* #define LOG_NDEBUG 0 */
#define LOG_TAG "ExynosCameraFrameManager"
#include <log/log.h>

#include "ExynosCameraFrameManager.h"

namespace android {

#define CREATE_WORKER_DEFAULT_MARGIN_MAX 200
#define CREATE_WORKER_DEFAULT_MARGIN_MIN 100

#define DELETE_WORKER_DEFAULT_MARGIN_MAX 200

#define RUN_THREAD_TIMEOUT (5000000000L) /* 5 sec */

FrameWorker::FrameWorker(const char* name, int cameraid, FRAMEMGR_OPER::MODE operMode)
{
    m_cameraId = cameraid;
    strncpy(m_name, name, EXYNOS_CAMERA_NAME_STR_SIZE - 1);
    m_operMode = operMode;
    m_init();
}

FrameWorker::~FrameWorker()
{
    m_deinit();
}

status_t FrameWorker::m_init()
{
    m_key = 0;
    m_enable = false;
    return 0;
}

status_t FrameWorker::m_deinit()
{
    return 0;
}

uint32_t FrameWorker::getKey()
{
    return m_key;
}

status_t FrameWorker::setKey(uint32_t key)
{
    m_key = key;
    return 0;
}

status_t FrameWorker::dump()
{
    CLOGE(" do not support dump function.");
    return NO_ERROR;
}

frame_key_queue_t* FrameWorker::getQueue()
{
    CLOGE(" do not support getQueue function.");
    return NULL;
}

status_t FrameWorker::m_setEnable(bool enable)
{
    Mutex::Autolock lock(m_enableLock);
    status_t ret = FRAMEMGR_ERRCODE::OK;
    m_enable = enable;
    return ret;
}

bool FrameWorker::m_getEnable()
{
    Mutex::Autolock lock(m_enableLock);
    return m_enable;
}

status_t FrameWorker::m_setMargin(int32_t maxMargin, int32_t minMargin)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    int32_t oldMin = m_nMinMargin;
    int32_t oldMax = m_nMaxMargin;

    if (minMargin <= 0)
        m_nMinMargin = CREATE_WORKER_DEFAULT_MARGIN_MIN;
    else
        m_nMinMargin = minMargin;

    if (maxMargin <= 0)
        m_nMaxMargin = CREATE_WORKER_DEFAULT_MARGIN_MAX;
    else
        m_nMaxMargin = maxMargin;

    if ((oldMin != m_nMinMargin) || (oldMax != m_nMaxMargin)) {
        CLOGD("margin is updated, margin[MAX/MIN]=(%d x %d) -> (%d x %d)", oldMax, oldMin, m_nMaxMargin, m_nMinMargin);
    }

    return ret;
}

int32_t FrameWorker::m_getMargin(FrameMargin marginType)
{
    int32_t ret = 0;

    switch(marginType) {
    case FRAME_MARGIN_MIN:
        ret = m_nMinMargin;
        break;
    case FRAME_MARGIN_MAX:
        ret = m_nMaxMargin;
        break;
    }

    return ret;
}

CreateWorker::CreateWorker(const char* name,
                            int cameraid,
                            FRAMEMGR_OPER::MODE operMode,
                            int32_t maxMargin,
                            int32_t minMargin):FrameWorker(name, cameraid, operMode)
{
    CLOGD(" Worker CREATE mode(%d) min_margin(%d) max_margin(%d)  ",
            operMode, minMargin, maxMargin);
    m_init();
    m_setMargin(maxMargin, minMargin);
}
CreateWorker::~CreateWorker()
{
    CLOGD(" Worker DELETE mode(%d) ", m_operMode);
    m_deinit();
}

status_t CreateWorker::m_deinit()
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    ExynosCameraFrameSP_sptr_t frame = NULL;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(false);
        if (m_worklist != NULL) {
            delete m_worklist;
            m_worklist = NULL;
        }

        if (m_lock != NULL) {
            delete m_lock;
            m_lock = NULL;
        }

        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(false);
        m_command.sendCommand(FrameWorkerCommand::STOP);
        m_thread->requestExitAndWait();
        m_command.cmdQ.release();
        m_setMargin(0, 0);
        if (m_worklist != NULL) {
            while (m_worklist->getSizeOfProcessQ() > 0) {
                m_worklist->popProcessQ(&frame);
                frame = NULL;
            }

            delete m_worklist;
            m_worklist = NULL;
        }

        if (m_lock != NULL) {
            delete m_lock;
            m_lock = NULL;
        }

        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return ret;
}

Mutex* CreateWorker::getLock()
{
    return m_lock;
}

status_t CreateWorker::execute(__unused ExynosCameraFrameSP_sptr_t inframe, ExynosCameraFrameSP_dptr_t outframe)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    if (m_getEnable() == false) {
        CLOGE(" invalid state, Need to start Worker before execute");
        ret = FRAMEMGR_ERRCODE::ERR;
        return ret;
    }

    outframe = m_execute();
    if (outframe == NULL) {
        CLOGE(" m_execute is invalid (outframe = NULL)");
        ret = FRAMEMGR_ERRCODE::ERR;
    }
    return ret;
}

status_t CreateWorker::setMargin(int32_t max, int32_t min)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    if (m_getEnable() == true) {
        CLOGE("invalid state, Need to stop Worker before update Info(%d %d)", min, max);
        ret = FRAMEMGR_ERRCODE::ERR;
        return ret;
    }

    m_setMargin(max, min);

    return ret;
}

status_t CreateWorker::start()
{
    if (m_worklist->getSizeOfProcessQ() > 0) {
        CLOGD("previous worklist size(%d)",
                 m_worklist->getSizeOfProcessQ());
        m_worklist->release();
    }

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(true);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(true);
        m_command.sendCommand(FrameWorkerCommand::START);

        if (m_thread->isRunning() == false) {
            m_command.sendCommand(FrameWorkerCommand::START);
        }
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }
    return 0;
}

status_t CreateWorker::stop()
{
    ExynosCameraFrameSP_sptr_t frame = NULL;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(false);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(false);
        m_command.sendCommand(FrameWorkerCommand::STOP);
        m_thread->requestExitAndWait();
        CLOGD(" worker stopped remove ths remained frames(%d)",
                 m_worklist->getSizeOfProcessQ());

        while (m_worklist->getSizeOfProcessQ() > 0) {
            m_worklist->popProcessQ(&frame);
            frame = NULL;
        }
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return 0;
}

ExynosCameraFrameSP_sptr_t CreateWorker::m_execute()
{
    ExynosCameraFrameSP_sptr_t frame = NULL;
    int32_t ret = NO_ERROR;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        frame = new ExynosCameraFrame(m_cameraId);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_worklist->popProcessQ(&frame);
        if (frame == NULL) {
            m_command.sendCommand(FrameWorkerCommand::START);
            m_worklist->waitAndPopProcessQ(&frame);
        }

        if (frame == NULL) {
            CLOGE("waitAndPopProcessQ failed, processQ size (%d) Thread return (%d) Status (%d)", m_worklist->getSizeOfProcessQ(), ret, m_thread->isRunning());
        }

        if (m_worklist->getSizeOfProcessQ() <= m_getMargin(FRAME_MARGIN_MIN))
            m_command.sendCommand(FrameWorkerCommand::START);

        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }
    return frame;
}

status_t CreateWorker::m_init()
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_worklist = new frame_manager_queue_t;
        m_lock = new Mutex();
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_thread =  new FrameManagerThread(this,
                                        static_cast<func_ptr_t_>(&CreateWorker::workerMain),
                                        "Create Frame Thread",
                                        PRIORITY_URGENT_DISPLAY);
        m_worklist = new frame_manager_queue_t;
        m_lock = new Mutex();

        m_command.cmdQ.setWaitTime(RUN_THREAD_TIMEOUT);
        m_command.cmdQ.setup(m_thread);
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        m_worklist = NULL;
        m_lock = NULL;
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        ret = FRAMEMGR_ERRCODE::ERR;
        break;
    }

    return ret;
}

bool CreateWorker::workerMain()
{
#ifdef DEBUG
    ExynosCameraAutoTimer autoTimer(__FUNCTION__);
#endif
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    bool loop = true;
    ExynosCameraFrameSP_sptr_t frame = NULL;
    uint32_t cmd = 0;
#if defined EXYNOS_CAMERA_FRAME_CREATE_PERFORMANCE
    uint32_t count = 0;
#endif

    if ((ret = m_command.waitCommand(&cmd)) < 0) {
        if (ret == TIMED_OUT)
            CLOGD("waiting time is expired");
        else
            CLOGE("wait and pop fail, restart, ret(%s(%d))", "ERROR", ret);

        return loop;
    }

#if defined EXYNOS_CAMERA_FRAME_CREATE_PERFORMANCE
    count = 0;
    m_createTimer.start();
#endif
    while ((m_getEnable() == true) && (cmd == FrameWorkerCommand::START)
        && (m_worklist->getSizeOfProcessQ() < m_getMargin(FRAME_MARGIN_MAX))) {
        frame = NULL;
        frame = new ExynosCameraFrame(m_cameraId);
        m_worklist->pushProcessQ(&frame);
#if defined EXYNOS_CAMERA_FRAME_CREATE_PERFORMANCE
        count++;
#endif
    }

#if defined EXYNOS_CAMERA_FRAME_CREATE_PERFORMANCE
	m_createTimer.stop();
    /* check performance frame create, total generated frame count * 1ms */
    if ((count > 0) && (m_createTimer.durationMsecs() > count))
        CLOGE("Total generated frameCount(%d) duration(%llu msec)", count, (unsigned long long)m_createTimer.durationMsecs());
#endif

    if ((m_getEnable() == false) && (cmd == FrameWorkerCommand::STOP)) {
        loop = false;
        CLOGD(" Create worker stopped delete current frame(%d)",
             m_worklist->getSizeOfProcessQ());

        m_worklist->release();
    }

    return loop;
}

DeleteWorker::DeleteWorker(const char* name,
                            int cameraid,
                            FRAMEMGR_OPER::MODE operMode,
                            int32_t maxMargin):FrameWorker(name, cameraid, operMode)
{
    CLOGD(" Worker CREATE mode(%d) ", operMode);
    m_operMode = operMode;
    m_setMargin(maxMargin, 0);
    m_init();
}

DeleteWorker::~DeleteWorker()
{
    CLOGD(" Worker DELETE mode(%d) ", m_operMode);
    m_deinit();
}

status_t DeleteWorker::m_deinit()
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    ExynosCameraFrameSP_sptr_t frame = NULL;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(false);
        if (m_worklist != NULL) {
            delete m_worklist;
            m_worklist = NULL;
        }

        if (m_lock != NULL) {
            delete m_lock;
            m_lock = NULL;
        }
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(false);
        m_command.sendCommand(FrameWorkerCommand::STOP);
        m_thread->requestExitAndWait();
        m_command.cmdQ.release();
        m_setMargin(0, 0);
        if (m_worklist != NULL) {

            m_worklist->release();

            delete m_worklist;
            m_worklist = NULL;
        }

        if (m_lock != NULL) {
            delete m_lock;
            m_lock = NULL;
        }
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return ret;
}

Mutex* DeleteWorker::getLock()
{
    return m_lock;
}

status_t DeleteWorker::execute(ExynosCameraFrameSP_sptr_t inframe, __unused ExynosCameraFrameSP_dptr_t outframe)
{
    status_t ret = FRAMEMGR_ERRCODE::OK;
    if (m_getEnable() == false) {
        CLOGE(" invalid state, Need to start Worker before execute");
        ret = FRAMEMGR_ERRCODE::ERR;
        return ret;
    }

    ret = m_execute(inframe);
    if (ret < 0) {
        CLOGE(" m_execute is invalid ret(%d)", ret);
        ret = FRAMEMGR_ERRCODE::ERR;
    }

    return ret;
}

status_t DeleteWorker::start()
{
    if (m_worklist->getSizeOfProcessQ() > 0) {
        CLOGD("previous worklist size(%d), clear worklist",
                 m_worklist->getSizeOfProcessQ());
        m_worklist->release();
    }

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(true);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(true);
        m_command.sendCommand(FrameWorkerCommand::START);

        if (m_thread->isRunning() == false)
            m_command.sendCommand(FrameWorkerCommand::START);
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }
    return 0;
}

status_t DeleteWorker::stop()
{
    ExynosCameraFrameSP_sptr_t frame = NULL;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(false);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(false);
        m_command.sendCommand(FrameWorkerCommand::STOP);
        m_thread->requestExitAndWait();
        CLOGD(" worker stopped remove ths remained frames(%d)",
             m_worklist->getSizeOfProcessQ());

        m_worklist->release();
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return 0;
}

status_t DeleteWorker::m_setMargin(int32_t maxMargin, int32_t minMargin)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    m_nMinMargin = minMargin;

    if (maxMargin <= 0)
        m_nMaxMargin = DELETE_WORKER_DEFAULT_MARGIN_MAX;

    return ret;
}

status_t DeleteWorker::m_execute(ExynosCameraFrameSP_sptr_t frame)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        frame = NULL;
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_worklist->pushProcessQ(&frame);
        if (m_worklist->getSizeOfProcessQ() > m_getMargin(FRAME_MARGIN_MAX))
            m_command.sendCommand(FrameWorkerCommand::START);
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }
    return ret;
}

status_t DeleteWorker::m_init()
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_worklist = new frame_manager_queue_t;
        m_lock = new Mutex();
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_thread =  new FrameManagerThread(this,
                            static_cast<func_ptr_t_>(&DeleteWorker::workerMain),
                            "Delete Frame Thread",
                            PRIORITY_URGENT_DISPLAY);
        m_worklist = new frame_manager_queue_t;
        m_lock = new Mutex();

        m_command.cmdQ.setWaitTime(RUN_THREAD_TIMEOUT);
        m_command.cmdQ.setup(m_thread);
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        m_worklist = NULL;
        m_lock = NULL;
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return ret;
}

bool DeleteWorker::workerMain()
{
#ifdef DEBUG
        ExynosCameraAutoTimer autoTimer(__FUNCTION__);
#endif
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    bool loop = true;
    ExynosCameraFrameSP_sptr_t frame = NULL;
    uint32_t cmd = 0;

    if ((ret = m_command.waitCommand(&cmd)) < 0) {
        if (ret == TIMED_OUT)
            CLOGD("waiting time is expired");
        else
            CLOGE("wait and pop fail, restart, ret(%s(%d))", "ERROR", ret);

        return loop;
    }

    m_worklist->release();

    if ((m_getEnable() == false) && (cmd == FrameWorkerCommand::STOP)) {
        loop = false;
    }

    return loop;
}

RunWorker::RunWorker(const char* name,
                           int cameraid,
                           FRAMEMGR_OPER::MODE operMode,
                           int32_t margin,
                           uint32_t dumpMargin):FrameWorker(name, cameraid, operMode)
{
    CLOGD(" Worker CREATE mode(%d) ", operMode);
    m_framekeyQueue = NULL;
    m_numOfMargin = margin;
    m_numOfDumpMargin = dumpMargin;
    m_init();
}

RunWorker::~RunWorker()
{
    CLOGD(" Worker DELETE mode(%d) ", m_operMode);
    m_deinit();
}

status_t RunWorker::m_deinit()
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    ExynosCameraFrameSP_sptr_t frame = NULL;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(false);
        m_worklist.clear();
        if (m_framekeyQueue != NULL) {
            m_framekeyQueue->release();
            delete m_framekeyQueue;
            m_framekeyQueue = NULL;
        }
        break;

    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(false);
        if (m_framekeyQueue != NULL) {
            stopThreadAndInputQ(m_thread, 1, m_framekeyQueue);
            delete m_framekeyQueue;
            m_framekeyQueue = NULL;
        } else {
            m_thread->requestExitAndWait();
        }
        m_worklist.clear();
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return ret;
}

Mutex* RunWorker::getLock()
{
    return &m_lock;
}

status_t RunWorker::execute(ExynosCameraFrameSP_sptr_t inframe, __unused ExynosCameraFrameSP_dptr_t outframe)
{
    status_t ret = FRAMEMGR_ERRCODE::OK;

    if (m_getEnable() == false) {
        CLOGE(" invalid state, Need to start Worker before execute");
        ret = FRAMEMGR_ERRCODE::ERR;
        return ret;
    }

    ret = m_execute(inframe);
    if (ret < 0) {
        CLOGE(" m_execute is invalid ret(%d)", ret);
        ret = FRAMEMGR_ERRCODE::ERR;
    }

    return ret;
}

status_t RunWorker::setMargin(int32_t max, int32_t min)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    CLOGD("worker(%d - %d) do not support change margin", min, max);

    return ret;
}

status_t RunWorker::start()
{
    if (m_worklist.size() > 0) {
        CLOGD(" previous worklist size(%d), clear worklist", (int)m_worklist.size());
        m_worklist.clear();
    }
    if (m_framekeyQueue->getSizeOfProcessQ() > 0) {
        CLOGD(" previous framekeyQueue size(%d), clear framekeyQueue", m_framekeyQueue->getSizeOfProcessQ());
        m_framekeyQueue->release();
    }

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(true);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(true);

        if (m_thread->isRunning() == false)
            m_thread->run();
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }
    return 0;
}

status_t RunWorker::stop()
{
    ExynosCameraFrameSP_sptr_t frame = NULL;
    uint32_t framekey = 0;
    status_t ret = NO_ERROR;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_setEnable(false);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_setEnable(false);
        m_thread->requestExit();
        m_framekeyQueue->wakeupAll();
        m_thread->requestExitAndWait();
        CLOGD(" worker stopped remove ths remained frames(%d) queue(%d)",
            (int)m_worklist.size(), (int)m_framekeyQueue->getSizeOfProcessQ());

        while (m_framekeyQueue->getSizeOfProcessQ() > 0) {
            framekey = 0;
            ret = m_framekeyQueue->popProcessQ(&framekey);
            if (ret < 0) {
                CLOGE(" wait and pop fail, ret(%d)", ret);
                continue;
            }

            ret = m_removeFrame(framekey, &m_worklist, &m_lock);
            if (ret < 0){
                CLOGE(" m_removeFrame fail, ret(%d)", ret);
                continue;
            }
        }

        break;
    case FRAMEMGR_OPER::NONE:
    default:
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return NO_ERROR;
}

status_t RunWorker::dump()
{
    Mutex::Autolock lock(m_lock);
    status_t ret = NO_ERROR;
    map<uint32_t, ExynosCameraFrameWP_t>::iterator iter;
    pair<map<uint32_t, ExynosCameraFrameWP_t>::iterator,bool> listRet;
    ExynosCameraFrameWP_t item = NULL;
    ExynosCameraFrameSP_t detect = NULL;

    int frameSize = m_worklist.size();

    if (frameSize == 0) {
        CLOGD(" No memory leak detected m_runningFrameList.size()(%d)", frameSize);
    } else {
        CLOGW(" %d memory leak detected m_runningFrameList.size()(%d)", frameSize, frameSize);
    }

    for (iter = m_worklist.begin() ; iter != m_worklist.end() ;) {
        item = iter->second;
        detect = item.promote();
        if (detect == 0) {
            CLOGW(" promote failed, already delete frame");
        } else {
            CLOGW(" delete memory leak detected FrameKey(%d) HAL-FrameCnt(%d) FrameType(%u)",
                detect->getUniqueKey(), detect->getFrameCount(), detect->getFrameType());
            detect.clear();
        }
        m_worklist.erase(iter++);
        item = NULL;
    }

    m_worklist.clear();

    return ret;
}

frame_key_queue_t* RunWorker::getQueue()
{
    if (m_framekeyQueue == NULL) {
        CLOGE(" getQueue fail, Queue == NULL ");
    }

    return m_framekeyQueue;
}

status_t RunWorker::m_execute(ExynosCameraFrameSP_dptr_t frame)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        ret = m_insertFrame(frame, &m_worklist, &m_lock);
        if (ret < 0) {
            CLOGE(" m_insertFrame fail, ret(%d)", ret);
        }
        break;
    case FRAMEMGR_OPER::SLIENT:
        ret = m_insertFrame(frame, &m_worklist, &m_lock);
        if (ret < 0) {
            CLOGE(" m_insertFrame fail, ret(%d)", ret);
        }

        if (m_thread->isRunning() == false){
            m_thread->run();
        }
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }
    return ret;
}

status_t RunWorker::m_init()
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
        m_worklist.clear();
        m_framekeyQueue = new frame_key_queue_t(m_numOfMargin);
        m_framekeyQueue->setWaitTime(RUN_THREAD_TIMEOUT);
        break;
    case FRAMEMGR_OPER::SLIENT:
        m_thread =  new FrameManagerThread(this,
                            static_cast<func_ptr_t_>(&RunWorker::workerMain),
                            "Run Frame Thread",
                            PRIORITY_URGENT_DISPLAY);
        m_worklist.clear();
        m_framekeyQueue = new frame_key_queue_t(m_numOfMargin);
        m_framekeyQueue->setWaitTime(RUN_THREAD_TIMEOUT);
        break;
    case FRAMEMGR_OPER::NONE:
    default:
        m_worklist.clear();
        m_framekeyQueue = NULL;
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return ret;
}

bool RunWorker::workerMain()
{
#ifdef DEBUG
        ExynosCameraAutoTimer autoTimer(__FUNCTION__);
#endif
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    bool loop = true;
    uint32_t framekey = 0;
    int size = 0;

    if (m_getEnable() == false) {
        loop = false;
        CLOGD(" Run worker stopped delete current frame(%d)", m_framekeyQueue->getSizeOfProcessQ());

        while (m_framekeyQueue->getSizeOfProcessQ() > 0) {
            framekey = 0;
            ret = m_framekeyQueue->popProcessQ(&framekey);
            if (ret < 0) {
                CLOGE(" wait and pop fail, ret(%d)", ret);
                continue;
            }

            ret = m_removeFrame(framekey, &m_worklist, &m_lock);
            if (ret < 0){
                CLOGE(" m_removeFrame fail, ret(%d)", ret);
                continue;
            }
        }
        return loop;
    }

    ret = m_framekeyQueue->waitAndPopProcessQ(&framekey);
    if (ret < 0) {
        CLOGI(" wait and pop fail, ret(%d)", ret);
        goto func_exit;
    }

    ret = m_removeFrame(framekey, &m_worklist, &m_lock);
    if (ret < 0){
        CLOGE(" m_removeFrame fail, ret(%d)", ret);
        goto func_exit;
    }

    size = m_framekeyQueue->getSizeOfProcessQ();

    for (int i = 0 ; i < size ; i++) {
        framekey = 0;
        ret = m_framekeyQueue->popProcessQ(&framekey);
        if (ret < 0) {
            CLOGE(" wait and pop fail, ret(%d)", ret);
            continue;
        }

        ret = m_removeFrame(framekey, &m_worklist, &m_lock);
        if (ret < 0){
            CLOGE(" m_removeFrame fail, ret(%d)", ret);
            continue;
        }
    }

    if (m_getSizeList() > m_numOfDumpMargin){
        m_dumpFrame();
    }

func_exit:

    if (m_framekeyQueue->getSizeOfProcessQ() > 0)
        loop = true;

    return loop;

}

status_t RunWorker::m_insertFrame(ExynosCameraFrameSP_dptr_t frame,
                                  map<uint32_t, ExynosCameraFrameWP_t> *list,
                                  Mutex *lock)
{
    lock->lock();
    pair<map<uint32_t, ExynosCameraFrameWP_t>::iterator,bool> listRet;
    status_t ret = FRAMEMGR_ERRCODE::OK;

    listRet = list->insert( pair<uint32_t, ExynosCameraFrameWP_t>(frame->getUniqueKey(), frame));
    if (listRet.second == false) {
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" insertFrame fail frame already exist!! HAL frameCnt(%d) UniqueKey (%u) ",
            frame->getFrameCount(), frame->getUniqueKey());
    }
    lock->unlock();
    return ret;
}

status_t RunWorker::m_removeFrame(ExynosCameraFrameSP_dptr_t frame, map<uint32_t, ExynosCameraFrameWP_t> *list, Mutex *lock)
{
    return m_removeFrame(frame->getUniqueKey(), list, lock);
}


status_t RunWorker::m_removeFrame(uint32_t frameKey, map<uint32_t, ExynosCameraFrameWP_t> *list, Mutex *lock)
{
    lock->lock();
    status_t ret = NO_ERROR;
    map<uint32_t, ExynosCameraFrameWP_t>::iterator iter;
    pair<map<uint32_t, ExynosCameraFrameWP_t>::iterator,bool> listRet;
    ExynosCameraFrameWP_t item = NULL;

    iter = list->find(frameKey);
    if (iter != list->end()) {
        item = iter->second;
        list->erase(iter);
    } else {
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" frame is not EXIST UniqueKey(%d)", frameKey);
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    return ret;
}

status_t RunWorker::m_setMargin(int32_t numOfMargin)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    m_numOfMargin = numOfMargin;
    return ret;
}

int32_t RunWorker::m_getMargin()
{
    return m_numOfMargin;
}

status_t RunWorker::m_dumpFrame()
{
    Mutex::Autolock lock(m_lock);
    status_t ret = NO_ERROR;

    map<uint32_t, ExynosCameraFrameWP_t>::iterator iter;
    ExynosCameraFrameWP_t frame = NULL;
    ExynosCameraFrameSP_sptr_t item = NULL;

    CLOGD("++++++++++++++++++++++++++++++");

    CLOGD("m_numOfDumpMargin(%d) m_runningFrameList.size()(%zu)",
         m_numOfDumpMargin, m_worklist.size());
    int testCount = 0;
    for (iter = m_worklist.begin() ; iter != m_worklist.end() ; ++iter) {
        frame = iter->second;
        item = frame.promote();
        if (item == 0) {
            CLOGW(" promote failed, already delete frame");
        } else {
            CLOGW(" delete memory leak detected FrameKey(%d) HAL-FrameCnt(%d) FrameType(%u)",
                item->getUniqueKey(), item->getFrameCount(), item->getFrameType());
        }

        if (++testCount >= 5)
            break;
    }

    CLOGD("------------------------------");

#ifdef AVOID_ASSERT_FRAME
        CLOGE(" too many frames - m_runningFrameList.size(%d)",
                 (int)m_worklist.size());
#else
        android_printAssert(NULL, LOG_TAG, "HACK For ANR DEBUGGING");
#endif

    return ret;
}

uint32_t RunWorker::m_getSizeList()
{
    Mutex::Autolock lock(m_lock);
    return m_worklist.size();
}

ExynosCameraFrameManager::ExynosCameraFrameManager(const char* name,
                                                            int cameraid,
                                                            FRAMEMGR_OPER::MODE operMode)
{
    m_cameraId = cameraid;
    strncpy(m_name, name, EXYNOS_CAMERA_NAME_STR_SIZE - 1);

    CLOGD(" FrameManager CREATE mode(%d)", operMode);

    m_setOperMode(operMode);
    m_init();
}

ExynosCameraFrameManager::~ExynosCameraFrameManager()
{
    CLOGD(" FrameManager DELETE mode(%d)", m_operMode);
    m_deinit();
}

ExynosCameraFrameSP_sptr_t ExynosCameraFrameManager::createFrame(ExynosCameraParameters *param, uint32_t framecnt, uint32_t frametype)
{
    return m_createFrame(param, framecnt, frametype);
}

status_t ExynosCameraFrameManager::setKeybox(sp<KeyBox> keybox)
{
    Mutex::Autolock lock(m_stateLock);
    m_keybox = keybox;
    return 0;
}

sp<KeyBox> ExynosCameraFrameManager::getKeybox()
{
    Mutex::Autolock lock(m_stateLock);
    return m_keybox;
}

status_t ExynosCameraFrameManager::setWorker(int key, sp<FrameWorker> worker)
{
    Mutex::Autolock lock(m_stateLock);
    map<uint32_t, sp<FrameWorker> >::iterator iter;
    pair<map<uint32_t, sp<FrameWorker> >::iterator,bool> workerRet;
    pair<map<uint32_t, Mutex*>::iterator,bool> mutexRet;

    iter = m_workerList.find(key);
    if (iter != m_workerList.end()) {
        CLOGE(" already worker is EXIST(%d)", key);
    } else {
        m_setupWorkerInfo(key, worker);
    }

    return 0;
}

status_t ExynosCameraFrameManager::setOperMode(FRAMEMGR_OPER::MODE mode)
{
   return m_setOperMode(mode);
}

int ExynosCameraFrameManager::getOperMode()
{
    return m_getOperMode();
}

status_t ExynosCameraFrameManager::m_init()
{
    int ret = FRAMEMGR_ERRCODE::OK;

    m_keybox = NULL;
    m_framekeyQueue = NULL;
    m_setEnable(false);
    return ret;
}

status_t ExynosCameraFrameManager::m_setupWorkerInfo(int key, sp<FrameWorker> worker)
{
    int ret = FRAMEMGR_ERRCODE::OK;
    pair<map<uint32_t, sp<FrameWorker> >::iterator,bool> workerRet;
    pair<map<uint32_t, Mutex*>::iterator,bool> mutexRet;

    workerRet = m_workerList.insert( pair<uint32_t, sp<FrameWorker> >(key, worker));
    if (workerRet.second == false) {
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" work insert failed(%d)", key);
    }
    return ret;
}

sp<FrameWorker> ExynosCameraFrameManager::getWorker(int key)
{
    Mutex::Autolock lock(m_stateLock);
    sp<FrameWorker> ret;
    map<uint32_t, sp<FrameWorker> >::iterator iter;

    if (m_getEnable() == true) {
        CLOGE("invalid state, Need to stop FrameMgr before getWorker(%d)", key);
        return NULL;
    }

    iter = m_workerList.find(key);
    if (iter != m_workerList.end()) {
        ret = iter->second;
    } else {
        CLOGE(" worker is not EXIST(%d)", key);
        ret = NULL;
    }

    return ret;
}

sp<FrameWorker> ExynosCameraFrameManager::eraseWorker(int key)
{
    Mutex::Autolock lock(m_stateLock);
    sp<FrameWorker> ret;
    map<uint32_t, sp<FrameWorker> >::iterator iter;

    iter = m_workerList.find(key);
    if (iter != m_workerList.end()) {
        ret = iter->second;
        m_workerList.erase(iter);
    } else {
        CLOGE(" worker is not EXIST(%d)", key);
        ret = NULL;
    }
    return ret;
}

status_t ExynosCameraFrameManager::start()
{
    Mutex::Autolock lock(m_stateLock);
    status_t ret = FRAMEMGR_ERRCODE::OK;
    sp<FrameWorker> worker = NULL;
    map<uint32_t, sp<FrameWorker> >::iterator iter;

    if (m_getEnable() == true) {
        CLOGD("frameManager already start!!");
        ret = INVALID_OPERATION;
        goto func_exit;
    }

    {
        iter = m_workerList.find(FRAMEMGR_WORKER::RUNNING);
        if (iter == m_workerList.end()) {
            CLOGE("do not find worker(%d) !!", FRAMEMGR_WORKER::RUNNING);
            ret = INVALID_OPERATION;
            goto func_exit;
        }
        worker = iter->second;
        m_framekeyQueue = worker->getQueue();
    }

    for (iter = m_workerList.begin() ; iter != m_workerList.end() ; ++iter) {
        worker = iter->second;
        ret = worker->start();
    }

    m_setEnable(true);

func_exit:
    return ret;
}

status_t ExynosCameraFrameManager::stop()
{
    Mutex::Autolock lock(m_stateLock);
    status_t ret = FRAMEMGR_ERRCODE::OK;
    sp<FrameWorker> worker;

    if (m_getEnable() == false) {
        CLOGD("frameManager already stop!!");
        return ret;
    }

    m_setEnable(false);

    map<uint32_t, sp<FrameWorker> >::iterator iter;
    for (iter = m_workerList.begin() ; iter != m_workerList.end() ; ++iter) {
        worker = iter->second;
        ret = worker->stop();
    }

    return ret;
}

int ExynosCameraFrameManager::deleteAllFrame()
{
    Mutex::Autolock lock(m_stateLock);
    status_t ret = NO_ERROR;
    ExynosCameraFrameSP_sptr_t frame = NULL;

    if (m_getEnable() == true) {
        CLOGE(" invalid state, module state enabled, state must disabled");
        ret = INVALID_OPERATION;
        return ret;
    }

    sp<FrameWorker> worker = NULL;
    map<uint32_t, sp<FrameWorker> >::iterator iter;
    iter = m_workerList.find(FRAMEMGR_WORKER::RUNNING);
    if (iter == m_workerList.end()) {
        CLOGE("do not find worker(%d) !!", FRAMEMGR_WORKER::RUNNING);
        ret = INVALID_OPERATION;
        goto func_exit;
    }
    worker = iter->second;
    worker->dump();

func_exit:
    return ret;
}

ExynosCameraFrameSP_sptr_t ExynosCameraFrameManager::m_createFrame(ExynosCameraParameters *param,
                                                                   uint32_t framecnt,
                                                                   uint32_t frametype)
{
    int ret = FRAMEMGR_ERRCODE::OK;
    uint32_t nextKey = 0;
    ExynosCameraFrameSP_sptr_t frame = NULL;
    ExynosCameraFrameSP_sptr_t outframe = NULL;
    map<uint32_t, sp<FrameWorker> >::iterator iter;
    sp<FrameWorker> worker = NULL;
    if (m_getEnable() == false) {
        CLOGE(" module state disabled");
        return frame;
    }

    iter = m_workerList.find(FRAMEMGR_WORKER::CREATE);
    worker = iter->second;

    switch (m_operMode) {
    case FRAMEMGR_OPER::ONDEMAND:
    case FRAMEMGR_OPER::SLIENT:
        worker->execute(NULL, frame);
        if (frame == NULL) {
            CLOGE("Frame is NULL");
            return frame;
        }

        frame->setUniqueKey(m_keybox->createKey());
        nextKey = m_keybox->getKey();
        if (nextKey == frame->getUniqueKey()) {
            CLOGW("[F%d]Failed to increase frameUniqueKey. curKey %d nextKey %d",
                    framecnt, frame->getUniqueKey(), nextKey);

            /* Increase the next frameUniqueKey forcely */
            nextKey += 1;
            m_keybox->setKey(nextKey);
        }
        frame->setFrameInfo(param ,framecnt, frametype);

        frame->setFrameMgrInfo(m_framekeyQueue);

        iter = m_workerList.find(FRAMEMGR_WORKER::RUNNING);
        if (iter != m_workerList.end()) {
            worker = iter->second;
        } else {
            CLOGE(" worker is not EXIST FRAMEMGR_WORKER::RUNNING");
        }

        ret = worker->execute(frame, outframe);
        if (ret < 0) {
            CLOGE("m_insertFrame is Failed ");
            return NULL;
        }
        break;
    }

    return frame;
}

status_t ExynosCameraFrameManager::dump()
{
    status_t ret = FRAMEMGR_ERRCODE::OK;

    return ret;
}

status_t ExynosCameraFrameManager::m_deinit()
{
    status_t ret = FRAMEMGR_ERRCODE::OK;
    ExynosCameraFrameSP_sptr_t frame = NULL;
    sp<FrameWorker> worker;

    map<uint32_t, sp<FrameWorker> >::iterator iter;
    for (iter = m_workerList.begin() ; iter != m_workerList.end() ; ++iter) {
        worker = iter->second;
        m_workerList.erase(iter++);
        worker = NULL;
    }

    m_workerList.clear();

    if (m_keybox != NULL) {
        CLOGD(" delete m_keybox");
        m_keybox = NULL;
    }

    m_framekeyQueue = NULL;

    return ret;
}

status_t ExynosCameraFrameManager::m_setOperMode(FRAMEMGR_OPER::MODE mode)
{
    int32_t ret = FRAMEMGR_ERRCODE::OK;
    switch (mode) {
    case FRAMEMGR_OPER::ONDEMAND:
    case FRAMEMGR_OPER::SLIENT:
        m_operMode = mode;
        break;
    default:
        m_operMode = -1;
        ret = FRAMEMGR_ERRCODE::ERR;
        CLOGE(" operMode is invalid operMode(%d)", m_operMode);
        break;
    }

    return ret;
}

int ExynosCameraFrameManager::m_getOperMode()
{
    return m_operMode;
}

status_t ExynosCameraFrameManager::m_setEnable(bool enable)
{
    Mutex::Autolock lock(m_enableLock);
    status_t ret = FRAMEMGR_ERRCODE::OK;
    m_enable = enable;
    return ret;
}

bool ExynosCameraFrameManager::m_getEnable()
{
    Mutex::Autolock lock(m_enableLock);
    return m_enable;
}




//************FrameManager END *************************//




}; /* namespace android */
