/*
 * Copyright (C) 2017, 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 "ExynosCameraRequestManager"

#include "ExynosCameraRequestManager.h"

namespace android {

ExynosCameraRequestResult::ExynosCameraRequestResult(uint32_t key, uint32_t requestKey, uint32_t frameCount, EXYNOS_REQUEST_RESULT::TYPE type)
{
    m_init();

    m_key = key;
    m_requestKey = requestKey;
    m_type = type;
    m_frameCount = frameCount;
}

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

status_t ExynosCameraRequestResult::m_init()
{
    status_t ret = NO_ERROR;
    m_key = 0;
    m_requestKey = 0;
    m_type = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;
    m_frameCount = 0;
    memset(&m_captureResult, 0x00, sizeof(camera3_capture_result_t));
    memset(&m_notityMsg, 0x00, sizeof(camera3_notify_msg_t));
    memset(&m_streamBuffer, 0x00, sizeof(camera3_stream_buffer_t));

    return ret;
}

status_t ExynosCameraRequestResult::m_deinit()
{
    status_t ret = NO_ERROR;
    m_key = 0;
    m_requestKey = 0;
    m_type = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;
    m_frameCount = 0;
    memset(&m_captureResult, 0x00, sizeof(camera3_capture_result_t));
    memset(&m_notityMsg, 0x00, sizeof(camera3_notify_msg_t));
    memset(&m_streamBuffer, 0x00, sizeof(camera3_stream_buffer_t));

    return ret;
}

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

uint32_t ExynosCameraRequestResult::getFrameCount()
{
    return m_frameCount;
}

uint32_t ExynosCameraRequestResult::getRequestKey()
{
    return m_requestKey;
}

EXYNOS_REQUEST_RESULT::TYPE ExynosCameraRequestResult::getType()
{
    EXYNOS_REQUEST_RESULT::TYPE ret = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;
    switch (m_type) {
    case EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ONLY:
    case EXYNOS_REQUEST_RESULT::CALLBACK_BUFFER_ONLY:
    case EXYNOS_REQUEST_RESULT::CALLBACK_ALL_RESULT:
    case EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA:
    case EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ERROR:
    case EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_SHUTTER:
        ret = m_type;
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_INVALID:
    default:
        CLOGE2("getResultType type have INVALID value type(%d) key(%u) frameCount(%u) ",
            m_type, m_key, m_frameCount);
        break;
    }
    return ret;
}

camera3_capture_result_t* ExynosCameraRequestResult::getCaptureResult()
{
    return &m_captureResult;
}

camera3_notify_msg_t* ExynosCameraRequestResult::getNotifyMsg()
{
    return &m_notityMsg;
}

camera3_stream_buffer_t* ExynosCameraRequestResult::getStreamBuffer()
{
    return &m_streamBuffer;
}

ExynosCameraRequest::ExynosCameraRequest(camera3_capture_request_t* request, CameraMetadata previousMeta)
{
    ExynosCameraStream *stream = NULL;
    int streamId = -1;

    if (request == NULL) {
        ALOGE("ERR(%s[%d]):capture_request is NULL", __FUNCTION__, __LINE__);
        return;
    }

    m_init();

    m_request = new camera3_capture_request_t;
    memcpy(m_request, request, sizeof(camera3_capture_request_t));

    m_inputStreamDone = false;
    for (int i = 0 ; i < HAL_STREAM_ID_MAX; i++) {
        m_streamIdList[i] = -1;
        m_outputStreamDone[i] = false;
    }

    /* Deep copy the input buffer object, because the Camera sevice can reuse it
       in successive request with different contents.
    */
    if(request->input_buffer != NULL) {
        CLOGD2("Allocating input buffer (%p)", request->input_buffer);
        m_request->input_buffer = new camera3_stream_buffer_t();
        memcpy(m_request->input_buffer, request->input_buffer, sizeof(camera3_stream_buffer_t));
    }

    m_key = m_request->frame_number;
    m_numOfOutputBuffers = request->num_output_buffers;
    m_isSkipMetaResult = false;
    m_isSkipCaptureResult = false;

    /* Deep copy the output buffer objects as well */
    if ((request->output_buffers != NULL) && (m_numOfOutputBuffers > 0)) {
        camera3_stream_buffer_t* newOutputBuffers = NULL;
        newOutputBuffers = new camera3_stream_buffer_t[m_numOfOutputBuffers];
        memcpy(newOutputBuffers, request->output_buffers, sizeof(camera3_stream_buffer_t) * m_numOfOutputBuffers);
        /* Nasty casting to assign a value to const pointer */
        *(camera3_stream_buffer_t**)(&m_request->output_buffers) = newOutputBuffers;

        for (int i = 0; i < m_numOfOutputBuffers; i++) {
            streamId = -1;
            stream = static_cast<ExynosCameraStream *>(request->output_buffers[i].stream->priv);
            stream->getID(&streamId);
            m_streamIdList[i] = streamId;
        }
    }

    if (request->settings != NULL) {
        m_serviceMeta = request->settings;
    } else {
        CLOGV2("serviceMeta is NULL, use previousMeta");
        if (previousMeta.isEmpty()) {
            CLOGE2("previous meta is empty, ERROR ");
        } else {
            m_serviceMeta = previousMeta;
        }
    }

    CLOGV2("key(%d), request->frame_count(%d), num_output_buffers(%d)",
        m_key, request->frame_number, request->num_output_buffers);

    m_previewFactoryAddrList.clear();
    m_captureFactoryAddrList.clear();

/*    m_serviceMeta = request->settings;*/
}

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

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

void ExynosCameraRequest::setFrameCount(uint32_t frameCount)
{
    m_frameCount = frameCount;
}

status_t ExynosCameraRequest::m_init()
{
    status_t ret = NO_ERROR;

    m_key = 0;
    m_request = NULL;
    m_requestId = 0;
    m_frameCount = 0;
    m_serviceMeta.clear();
    memset(&m_serviceShot, 0x00, sizeof(struct camera2_shot_ext));
    memset(&m_metaParameters, 0x00, sizeof(struct CameraMetaParameters));
    m_metaParameters.m_zoomRatio = 1.0f;

    for (int i = 0; i < INTERFACE_TYPE_MAX; i++) {
        m_serviceShot.shot.uctl.scalerUd.mcsc_sub_blk_port[i] = MCSC_PORT_NONE;
    }

    m_requestState = EXYNOS_REQUEST::STATE_SERVICE;
    m_factoryMap.clear();
    m_acquireFenceDoneMap.clear();
    m_numOfCompleteBuffers = 0;
    m_pipelineDepth = 0;

    for (int i = 0 ; i < EXYNOS_REQUEST_RESULT::CALLBACK_MAX ; i++) {
        m_resultStatus[i] = false;
    }

    m_inputStreamStatus = CAMERA3_BUFFER_STATUS_OK;
    for (int i = 0; i < HAL_STREAM_ID_MAX; i++) {
        m_outputStreamStatus[i] = CAMERA3_BUFFER_STATUS_OK;
    }
    m_sensorTimeStampBoot = 0;

    return ret;
}

status_t ExynosCameraRequest::m_deinit()
{
    status_t ret = NO_ERROR;

    if (m_request != NULL) {
        if (m_request->input_buffer != NULL) {
            delete m_request->input_buffer;
        }
        if (m_request->output_buffers != NULL) {
            delete[] m_request->output_buffers;
        }

        delete m_request;
        m_request = NULL;
    }

    m_frameCount = 0;
    m_serviceMeta = NULL;
    memset(&m_serviceShot, 0x00, sizeof(struct camera2_shot_ext));
    memset(&m_metaParameters, 0x00, sizeof(struct CameraMetaParameters));
    m_requestState = EXYNOS_REQUEST::STATE_SERVICE;
    resetCompleteBufferCount();

    for (int i = 0 ; i < EXYNOS_REQUEST_RESULT::CALLBACK_MAX ; i++) {
        m_resultStatus[i] = false;
    }

    m_previewFactoryAddrList.clear();
    m_captureFactoryAddrList.clear();

    return ret;
}


uint32_t ExynosCameraRequest::getFrameCount()
{
    return m_frameCount;
}

camera3_capture_request_t* ExynosCameraRequest::getServiceRequest()
{
    if (m_request == NULL)
    {
        CLOGE2("getServiceRequest is NULL m_request(%p) ", m_request);
    }
    return m_request;
}

CameraMetadata* ExynosCameraRequest::getServiceMeta()
{
    return &m_serviceMeta;
}

struct camera2_shot_ext* ExynosCameraRequest::getServiceShot()
{
    return &m_serviceShot;
}

struct CameraMetaParameters* ExynosCameraRequest::getMetaParameters()
{
    return &m_metaParameters;
}

void ExynosCameraRequest::setRequestLock()
{
    m_requestLock.lock();
}

void ExynosCameraRequest::setRequestUnlock()
{
    m_requestLock.unlock();
}

status_t ExynosCameraRequest::setRequestState(EXYNOS_REQUEST::STATE state)
{
    status_t ret = NO_ERROR;
    switch (state) {
    case EXYNOS_REQUEST::STATE_ERROR:
    case EXYNOS_REQUEST::STATE_SERVICE:
    case EXYNOS_REQUEST::STATE_RUNNING:
        m_requestState = state;
        break;
    default:
        CLOGE2("setState is invalid newstate(%d) ", state);
        break;
    }

    return ret;
}

EXYNOS_REQUEST::STATE ExynosCameraRequest::getRequestState(void)
{
    EXYNOS_REQUEST::STATE ret = EXYNOS_REQUEST::STATE_INVALID;
    switch (m_requestState) {
    case EXYNOS_REQUEST::STATE_ERROR:
    case EXYNOS_REQUEST::STATE_SERVICE:
    case EXYNOS_REQUEST::STATE_RUNNING:
        ret = m_requestState;
        break;
    case EXYNOS_REQUEST::STATE_INVALID:
    default:
        CLOGE2("getState is invalid curstate(%d) ", m_requestState);
        break;
    }

    return ret;
}

uint32_t ExynosCameraRequest::getNumOfInputBuffer()
{
    uint32_t numOfInputBuffer = 0;
    if (m_request->input_buffer != NULL) {
        numOfInputBuffer = 1;
    }
    return numOfInputBuffer;
}

camera3_stream_buffer_t* ExynosCameraRequest::getInputBuffer()
{
    if (m_request == NULL){
        CLOGE2("getInputBuffer m_request is NULL m_request(%p) ", m_request);
        return NULL;
    }

    if (m_request->input_buffer == NULL){
        CLOGV2("getInputBuffer input_buffer is NULL m_request(%p) ", m_request->input_buffer);
    }

    return m_request->input_buffer;
}

uint64_t ExynosCameraRequest::getSensorTimestamp()
{
    return m_sensorTimeStampBoot;
}

void ExynosCameraRequest::setSensorTimestamp(uint64_t timeStamp)
{
    m_sensorTimeStampBoot = timeStamp;
}

uint32_t ExynosCameraRequest::getNumOfOutputBuffer()
{
    return m_numOfOutputBuffers;
}

void ExynosCameraRequest::increaseCompleteBufferCount(void)
{
    m_resultStatusLock.lock();
    m_numOfCompleteBuffers++;
    m_resultStatusLock.unlock();
}

void ExynosCameraRequest::resetCompleteBufferCount(void)
{
    m_resultStatusLock.lock();
    m_numOfCompleteBuffers = 0;
    m_resultStatusLock.unlock();
}

int ExynosCameraRequest::getCompleteBufferCount(void)
{
     return m_numOfCompleteBuffers;
}

const camera3_stream_buffer_t* ExynosCameraRequest::getOutputBuffers()
{
    if (m_request == NULL){
        CLOGE2("utputBuffer m_request is NULL m_request(%p) ", m_request);
        return NULL;
    }

    if (m_request->output_buffers == NULL){
        CLOGE2("getNumOfOutputBuffer output_buffers is NULL m_request(%p) ",
            m_request->output_buffers);
        return NULL;
    }

    CLOGV2("m_request->output_buffers(%p)", m_request->output_buffers);

    return m_request->output_buffers;
}

void ExynosCameraRequest::setRequestId(int reqId) {
    m_requestId = reqId;
}

int ExynosCameraRequest::getRequestId(void) {
    return m_requestId;
}

status_t ExynosCameraRequest::m_push(int key, ExynosCameraFrameFactory* item, FrameFactoryMap *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<FrameFactoryMap::iterator,bool> listRet;
    lock->lock();
    listRet = list->insert( pair<uint32_t, ExynosCameraFrameFactory*>(key, item));
    if (listRet.second == false) {
        ret = INVALID_OPERATION;
        CLOGE2("m_push failed, request already exist!! Request frameCnt( %d )", key);
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequest::m_pop(int key, ExynosCameraFrameFactory** item, FrameFactoryMap *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<FrameFactoryMap::iterator,bool> listRet;
    FrameFactoryMapIterator iter;
    ExynosCameraFrameFactory *factory = NULL;

    lock->lock();
    iter = list->find(key);
    if (iter != list->end()) {
        factory = iter->second;
        *item = factory;
        list->erase( iter );
    } else {
        CLOGE2("m_pop failed, factory is not EXIST Request frameCnt( %d )", key);
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequest::m_get(int streamID, ExynosCameraFrameFactory** item, FrameFactoryMap *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<FrameFactoryMap::iterator,bool> listRet;
    FrameFactoryMapIterator iter;
    ExynosCameraFrameFactory *factory = NULL;

    lock->lock();
    iter = list->find(streamID);
    if (iter != list->end()) {
        factory = iter->second;
        *item = factory;
    } else {
        CLOGE2("m_pop failed, request is not EXIST Request streamID( %d )", streamID);
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    return ret;
}

bool ExynosCameraRequest::m_find(int streamID, FrameFactoryMap *list, Mutex *lock)
{
    bool ret = false;
    pair<FrameFactoryMap::iterator,bool> listRet;
    FrameFactoryMapIterator iter;

    lock->lock();
    iter = list->find(streamID);
    if (iter != list->end()) {
        ret = true;
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequest::m_getList(FrameFactoryList *factorylist, FrameFactoryMap *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    FrameFactoryMapIterator iter;
    ExynosCameraFrameFactory *factory = NULL;

    lock->lock();
    for (iter = list->begin(); iter != list->end() ; iter++) {
        factory = iter->second;
        factorylist->push_back(factory);
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequest::pushFrameFactory(int StreamID, ExynosCameraFrameFactory* factory)
{
    status_t ret = NO_ERROR;
    ret = m_push(StreamID % HAL_STREAM_ID_MAX, factory, &m_factoryMap, &m_factoryMapLock);
    if (ret < 0) {
        CLOGE2("pushFrameFactory is failed StreamID(%d) factory(%p)", StreamID, factory);
    }

    return ret;
}

ExynosCameraFrameFactory* ExynosCameraRequest::popFrameFactory(int streamID)
{
    status_t ret = NO_ERROR;
    ExynosCameraFrameFactory* factory = NULL;

    ret = m_pop(streamID % HAL_STREAM_ID_MAX, &factory, &m_factoryMap, &m_factoryMapLock);
    if (ret < 0) {
        CLOGE2("popFrameFactory is failed StreamID(%d) factory(%p)", streamID, factory);
    }
    return factory;
}

ExynosCameraFrameFactory* ExynosCameraRequest::getFrameFactory(int streamID)
{
    status_t ret = NO_ERROR;
    ExynosCameraFrameFactory* factory = NULL;

    ret = m_get(streamID % HAL_STREAM_ID_MAX, &factory, &m_factoryMap, &m_factoryMapLock);
    if (ret < 0) {
        CLOGE2("getFrameFactory is failed StreamID(%d) factory(%p)", streamID, factory);
    }

    return factory;
}

bool ExynosCameraRequest::isFrameFactory(int streamID)
{
    return m_find(streamID % HAL_STREAM_ID_MAX, &m_factoryMap, &m_factoryMapLock);
}

status_t ExynosCameraRequest::getFrameFactoryList(FrameFactoryList *list)
{
    status_t ret = NO_ERROR;

    ret = m_getList(list, &m_factoryMap, &m_factoryMapLock);
    if (ret < 0) {
        CLOGE2("getFrameFactoryList is failed");
    }

    return ret;
}

status_t ExynosCameraRequest::setFactoryAddrList(ExynosCameraFrameFactory *factoryAddr[FRAME_FACTORY_TYPE_MAX])
{
    status_t ret = NO_ERROR;

    for (int factoryTypeIdx = 0; factoryTypeIdx < FRAME_FACTORY_TYPE_MAX; factoryTypeIdx++) {
        if (factoryAddr[factoryTypeIdx] != NULL) {
            if (factoryTypeIdx == FRAME_FACTORY_TYPE_REPROCESSING) {
                m_captureFactoryAddrList.push_back(factoryAddr[factoryTypeIdx]);
            } else if (factoryTypeIdx == FRAME_FACTORY_TYPE_CAPTURE_PREVIEW
                       || factoryTypeIdx == FRAME_FACTORY_TYPE_VISION) {
                m_previewFactoryAddrList.push_back(factoryAddr[factoryTypeIdx]);
            }
        }
    }

    return ret;
}

status_t ExynosCameraRequest::getFactoryAddrList(enum FRAME_FACTORY_TYPE factoryType, FrameFactoryList *list)
{
    status_t ret = NO_ERROR;
    FrameFactoryListIterator iter;
    ExynosCameraFrameFactory *factory = NULL;

    if (factoryType== FRAME_FACTORY_TYPE_REPROCESSING) {
        for (iter = m_captureFactoryAddrList.begin(); iter != m_captureFactoryAddrList.end(); ) {
            factory = *iter;
            list->push_back(factory);
            iter++;
        }
    } else if (factoryType == FRAME_FACTORY_TYPE_CAPTURE_PREVIEW
               || factoryType == FRAME_FACTORY_TYPE_VISION) {
        for (iter = m_previewFactoryAddrList.begin(); iter != m_previewFactoryAddrList.end(); ) {
            factory = *iter;
            list->push_back(factory);
            iter++;
        }
    }

    return ret;
}

status_t ExynosCameraRequest::getAllRequestOutputStreams(List<int> **list)
{
    status_t ret = NO_ERROR;

    CLOGV2("m_requestOutputStreamList.size(%zu)", m_requestOutputStreamList.size());

    /* lock->lock(); */
    *list = &m_requestOutputStreamList;
    /* lock->unlock(); */

    return ret;
}

status_t ExynosCameraRequest::pushRequestOutputStreams(int requestStreamId)
{
    status_t ret = NO_ERROR;

    /* lock->lock(); */
    m_requestOutputStreamList.push_back(requestStreamId);
    /* lock->unlock(); */

    return ret;
}

status_t ExynosCameraRequest::getAllRequestInputStreams(List<int> **list)
{
    status_t ret = NO_ERROR;

    CLOGV2("m_requestOutputStreamList.size(%zu)", m_requestInputStreamList.size());

    /* lock->lock(); */
    *list = &m_requestInputStreamList;
    /* lock->unlock(); */

    return ret;
}

status_t ExynosCameraRequest::pushRequestInputStreams(int requestStreamId)
{
    status_t ret = NO_ERROR;

    /* lock->lock(); */
    m_requestInputStreamList.push_back(requestStreamId);
    /* lock->unlock(); */

    return ret;
}

status_t ExynosCameraRequest::setAcquireFenceDone(buffer_handle_t *handle, bool done)
{
    status_t ret = NO_ERROR;
    pair<map<buffer_handle_t *, bool>::iterator, bool> listRet;
    Mutex::Autolock l(m_acquireFenceDoneLock);
    listRet = m_acquireFenceDoneMap.insert(pair<buffer_handle_t *, bool>(handle, done));
    if (listRet.second == false) {
        map<buffer_handle_t *, bool>::iterator iter = m_acquireFenceDoneMap.find(handle);
        bool fenceDone = false;

        if (iter != m_acquireFenceDoneMap.end()) {
            fenceDone = iter->second;
            if (fenceDone != done) {
                m_acquireFenceDoneMap.at(handle) = done;
                CLOGW2("[R%d F%d] duplicate KEY, value old: %s/ new: %s",
                        m_key, m_frameCount,
                        fenceDone == true ? "Done" : "Wait",
                        done == true ? "Done" : "Wait");
            }
        } else {
            ret = INVALID_OPERATION;
            CLOGE2("[R%d F%d] m_pop failed, handle is not EXIST",
                    m_key, m_frameCount);
        }
    }

    return ret;
}

bool ExynosCameraRequest::getAcquireFenceDone(buffer_handle_t *handle)
{
    bool fenceDone = false;
    pair<map<buffer_handle_t *, bool>::iterator, bool> listRet;
    map<buffer_handle_t *, bool>::iterator iter;
    ExynosCameraRequestSP_sprt_t request = NULL;

    Mutex::Autolock l(m_acquireFenceDoneLock);
    iter = m_acquireFenceDoneMap.find(handle);
    if (iter != m_acquireFenceDoneMap.end()) {
        fenceDone = iter->second;
    } else {
        CLOGE2("[R%d F%d] m_pop failed, handle is not EXIST",
                m_key, m_frameCount);
        fenceDone = false;
    }

    return fenceDone;
}

status_t ExynosCameraRequest::setCallbackDone(EXYNOS_REQUEST_RESULT::TYPE reqType, bool flag)
{
    status_t ret = NO_ERROR;
    ret = m_setCallbackDone(reqType, flag, &m_resultStatusLock);
    if (ret < 0) {
        CLOGE2("m_get request is failed, request type(%d) ", reqType);
    }

    return ret;
}

bool ExynosCameraRequest::getCallbackDone(EXYNOS_REQUEST_RESULT::TYPE reqType)
{
    bool ret = false;
    ret = m_getCallbackDone(reqType, &m_resultStatusLock);
    return ret;
}

status_t ExynosCameraRequest::setCallbackStreamDone(int streamId, bool flag)
{
    status_t ret = NO_ERROR;
    ret = m_setCallbackStreamDone(streamId, flag, &m_resultStatusLock);
    if (ret < 0) {
        CLOGE2("[R%d F%d S%d] setCallbackStreamDone is failed.", m_key, m_frameCount, streamId);
    }

    return ret;
}

bool ExynosCameraRequest::getCallbackStreamDone(int streamId)
{
    bool ret = false;
    ret = m_getCallbackStreamDone(streamId, &m_resultStatusLock);
    return ret;
}

bool ExynosCameraRequest::isComplete()
{
    bool ret = false;
    bool notify = false;
    bool partial = false;
    bool capture = false;

    notify = m_getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ONLY, &m_resultStatusLock);
    partial = m_getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA, &m_resultStatusLock);
    capture = m_getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_ALL_RESULT, &m_resultStatusLock);

    if (notify == true && capture == true && partial == true) {
        ret = true;
    }

    return ret;
}

int ExynosCameraRequest::getStreamIdwithBufferIdx(int bufferIndex)
{
    if (bufferIndex < 0 || bufferIndex >= m_numOfOutputBuffers) {
        CLOGE2("Invalid buffer index(%d), outputBufferCount(%d)",
                bufferIndex, m_numOfOutputBuffers);
        return -1;
    }

    if (m_streamIdList[bufferIndex] < 0) {
        CLOGE2("m_streamIdList is NULL, index(%d)", bufferIndex);
        return -1;
    }

    return m_streamIdList[bufferIndex];
}

bool ExynosCameraRequest::hasStream(int streamIdx)
{
    if (streamIdx >= HAL_STREAM_ID_MAX) {
        CLOGE2("Invalid Stream id (%d)", streamIdx);
        return false;
    }

    for (int i = 0; i < m_numOfOutputBuffers; i++) {
        if ((m_streamIdList[i] % HAL_STREAM_ID_MAX) == streamIdx) {
            return true;
        }
    }

    return false;
}

int ExynosCameraRequest::getStreamIdwithStreamIdx(int streamIdx)
{
    if (streamIdx >= HAL_STREAM_ID_MAX) {
        CLOGE2("Invalid Stream id (%d)", streamIdx);
        return -1;
    }

    for (int i = 0; i < m_numOfOutputBuffers; i++) {
        if ((m_streamIdList[i] % HAL_STREAM_ID_MAX) == streamIdx) {
            return m_streamIdList[i];
        }
    }

    return -1;
}

int ExynosCameraRequest::getBufferIndex(int streamId)
{
    int index = -1;

    if (streamId % HAL_STREAM_ID_MAX >= HAL_STREAM_ID_MAX) {
        CLOGE2("Invalid Stream id (%d)", streamId);
        return -1;
    }

    for (int i = 0; i < m_numOfOutputBuffers; i++) {
        if (streamId == m_streamIdList[i]) {
            index = i;
            break;
        }
    }

    return index;
}

void ExynosCameraRequest::increasePipelineDepth(void)
{
    m_pipelineDepth++;
}

void ExynosCameraRequest::updatePipelineDepth(void)
{
    const uint8_t pipelineDepth = m_pipelineDepth;

    m_serviceShot.shot.dm.request.pipelineDepth = m_pipelineDepth;
    m_serviceMeta.update(ANDROID_REQUEST_PIPELINE_DEPTH, &pipelineDepth, 1);
    CLOGV2("ANDROID_REQUEST_PIPELINE_DEPTH(%d)", pipelineDepth);
}

CameraMetadata ExynosCameraRequest::get3AAResultMeta(void)
{
    uint8_t entry;
    CameraMetadata minimal_resultMeta;

    if (m_serviceMeta.exists(ANDROID_CONTROL_AF_MODE)) {
        entry = m_serviceMeta.find(ANDROID_CONTROL_AF_MODE).data.u8[0];
        minimal_resultMeta.update(ANDROID_CONTROL_AF_MODE, &entry, 1);
        CLOGV2("ANDROID_CONTROL_CONTROL_AF_MODE is (%d)", entry);
    }

    if (m_serviceMeta.exists(ANDROID_CONTROL_AWB_MODE)) {
        entry = m_serviceMeta.find(ANDROID_CONTROL_AWB_MODE).data.u8[0];
        minimal_resultMeta.update(ANDROID_CONTROL_AWB_MODE, &entry, 1);
        CLOGV2("ANDROID_CONTROL_CONTROL_AWB_MODE is (%d)", entry);
    }

    if (m_serviceMeta.exists(ANDROID_CONTROL_AE_STATE)) {
        entry = m_serviceMeta.find(ANDROID_CONTROL_AE_STATE).data.u8[0];
        minimal_resultMeta.update(ANDROID_CONTROL_AE_STATE, &entry, 1);
        CLOGV2("ANDROID_CONTROL_CONTROL_AE_MODE is (%d)", entry);
    }

    if (m_serviceMeta.exists(ANDROID_CONTROL_AF_STATE)) {
        entry = m_serviceMeta.find(ANDROID_CONTROL_AF_STATE).data.u8[0];
        minimal_resultMeta.update(ANDROID_CONTROL_AF_STATE, &entry, 1);
        CLOGV2("ANDROID_CONTROL_CONTROL_AF_STATE is (%d)", entry);
    }

    if (m_serviceMeta.exists(ANDROID_CONTROL_AWB_STATE)) {
        entry = m_serviceMeta.find(ANDROID_CONTROL_AWB_STATE).data.u8[0];
        minimal_resultMeta.update(ANDROID_CONTROL_AWB_STATE, &entry, 1);
        CLOGV2("ANDROID_CONTROL_CONTROL_AWB_STATE is (%d)", entry);
    }

    get3AAResultMetaVendor(minimal_resultMeta);

    return minimal_resultMeta;
}

CameraMetadata ExynosCameraRequest::getShutterMeta()
{
    CameraMetadata minimal_resultMeta;

#ifdef SAMSUNG_TN_FEATURE
    uint8_t entry = 1;
    minimal_resultMeta.update(SAMSUNG_ANDROID_CONTROL_SHUTTER_NOTIFICATION, &entry, 1);
    CLOGV2("SAMSUNG_ANDROID_CONTROL_SHUTTER_NOTIFICATION is (%d)", entry);
#endif

    return minimal_resultMeta;
}

void ExynosCameraRequest::setSkipMetaResult(bool skip)
{
    Mutex::Autolock l(m_SkipMetaResultLock);
    m_isSkipMetaResult = skip;
}

bool ExynosCameraRequest::getSkipMetaResult(void)
{
    Mutex::Autolock l(m_SkipMetaResultLock);
    return m_isSkipMetaResult;
}

void ExynosCameraRequest::setSkipCaptureResult(bool skip)
{
    Mutex::Autolock l(m_SkipCaptureResultLock);
    m_isSkipCaptureResult = skip;
}

bool ExynosCameraRequest::getSkipCaptureResult(void)
{
    Mutex::Autolock l(m_SkipCaptureResultLock);
    return m_isSkipCaptureResult;
}

void ExynosCameraRequest::setDsInputPortId(int dsInputPortId)
{
    m_dsInputPortId = dsInputPortId;
}

int ExynosCameraRequest::getDsInputPortId(void)
{
    return m_dsInputPortId;
}

bool ExynosCameraRequest::m_isInputStreamId(int streamId)
{
    camera3_stream_buffer_t *inputBuffer = NULL;
    camera3_stream_t *serviceStream = NULL;
    ExynosCameraStream *stream = NULL;
    int id = 0;

    if (streamId < 0) {
        ALOGE("ERR(%s[%d]):streamId is INVALID", __FUNCTION__, __LINE__);
        return -1;
    }

    inputBuffer = getInputBuffer();
    if (inputBuffer == NULL) {
        ALOGV("DEBUG(%s[%d]):inputBuffer is NULL", __FUNCTION__, __LINE__);
        return false;
    }

    serviceStream = inputBuffer->stream;
    if (serviceStream == NULL) {
        ALOGE("ERR(%s[%d]):serviceStream is NULL", __FUNCTION__, __LINE__);
        return false;
    }

    stream = static_cast<ExynosCameraStream *>(serviceStream->priv);
    if (stream == NULL) {
        ALOGE("ERR(%s[%d]):stream is NULL", __FUNCTION__, __LINE__);
        return false;
    }

    stream->getID(&id);
    if (id != streamId) {
         ALOGV("DEBUG(%s[%d]):not inputStreamId", __FUNCTION__, __LINE__);
         return false;
    }

    return true;
}

int ExynosCameraRequest::m_getOutputBufferIndex(int streamId)
{
    if (streamId < 0) {
        ALOGE("ERR(%s[%d]):streamId is INVALID", __FUNCTION__, __LINE__);
        return -1;
    }

    for (int streamIndex = 0 ; streamIndex < m_numOfOutputBuffers; streamIndex++) {
        if (m_streamIdList[streamIndex] == streamId) {
            ALOGV("DEBUG(%s[%d]):Find output stream index. streamId(%d), streamIndex(%d)",
                    __FUNCTION__, __LINE__, streamId, streamIndex);
            return streamIndex;
        }
    }

    ALOGV("DEBUG(%s[%d]):Stream index not found from stream ID list. streamId(%d)",
            __FUNCTION__, __LINE__, streamId);

    return -1;
}

status_t ExynosCameraRequest::m_setCallbackDone(EXYNOS_REQUEST_RESULT::TYPE reqType, bool flag, Mutex *lock)
{
    status_t ret = NO_ERROR;
    if (reqType >= EXYNOS_REQUEST_RESULT::CALLBACK_MAX) {
        CLOGE2("m_setCallback failed, status erray out of bounded reqType(%d)", reqType);

        ret = INVALID_OPERATION;
        return ret;
    }

    lock->lock();
    m_resultStatus[reqType] = flag;
    lock->unlock();
    return ret;
}

bool ExynosCameraRequest::m_getCallbackDone(EXYNOS_REQUEST_RESULT::TYPE reqType, Mutex *lock)
{
    bool ret = false;
    if (reqType >= EXYNOS_REQUEST_RESULT::CALLBACK_MAX) {
        CLOGE2("m_getCallback failed, status erray out of bounded reqType(%d)", reqType);

        return ret;
    }

    lock->lock();
    ret = m_resultStatus[reqType];
    lock->unlock();
    return ret;
}

status_t ExynosCameraRequest::m_setCallbackStreamDone(int streamId, bool flag, Mutex *lock)
{
    int index = m_getOutputBufferIndex(streamId);
    if (index == -1) {
        if (m_isInputStreamId(streamId) == true) {
            Mutex::Autolock l(lock);
            m_inputStreamDone = flag;
        } else {
            ALOGE("ERR(%s[%d]):streamId(%d) is mismatched", __FUNCTION__, __LINE__, streamId);
            return NAME_NOT_FOUND;
        }
    } else {
        Mutex::Autolock l(lock);
        m_outputStreamDone[index] = flag;
    }

    return NO_ERROR;
}

bool ExynosCameraRequest::m_getCallbackStreamDone(int streamId, Mutex *lock)
{
    bool ret = false;
    int index = m_getOutputBufferIndex(streamId);
    if (index == -1) {
        if (m_isInputStreamId(streamId) == true) {
            Mutex::Autolock l(lock);
            ret = m_inputStreamDone;
        } else {
            ALOGE("ERR(%s[%d]):streamId(%d) is mismatched", __FUNCTION__, __LINE__, streamId);
            return false;
        }
    } else {
        Mutex::Autolock l(lock);
        ret = m_outputStreamDone[index];
    }

    return ret;
}

status_t ExynosCameraRequest::m_setStreamBufferStatus(int streamId, camera3_buffer_status_t status, Mutex *lock)
{
    int index = m_getOutputBufferIndex(streamId);
    if (index == -1) {
        if (m_isInputStreamId(streamId) == true) {
            Mutex::Autolock l(lock);
            m_inputStreamStatus = status;
        } else {
            ALOGE("ERR(%s[%d]):streamId(%d) is mismatched", __FUNCTION__, __LINE__, streamId);
            return NAME_NOT_FOUND;
        }
    } else {
        Mutex::Autolock l(lock);
        m_outputStreamStatus[index] = status;
    }

    return NO_ERROR;
}

camera3_buffer_status_t ExynosCameraRequest::m_getStreamBufferStatus(int streamId, Mutex *lock)
{
    camera3_buffer_status_t status = CAMERA3_BUFFER_STATUS_ERROR;

    int index = m_getOutputBufferIndex(streamId);
    if (index == -1) {
        if (m_isInputStreamId(streamId) == true) {
            Mutex::Autolock l(lock);
            status = m_inputStreamStatus;
        } else {
            ALOGE("ERR(%s[%d]):streamId(%d) is mismatched", __FUNCTION__, __LINE__, streamId);
            return CAMERA3_BUFFER_STATUS_ERROR;
        }
    } else {
        Mutex::Autolock l(lock);
        status = m_outputStreamStatus[index];
    }

    return status;
}

void ExynosCameraRequest::printCallbackDoneState()
{
    for (int i = 0 ; i < EXYNOS_REQUEST_RESULT::CALLBACK_MAX ; i++)
        CLOGD2("m_key(%d), m_resultStatus[%d](%d)", m_key, i, m_resultStatus[i]);
}

status_t ExynosCameraRequest::setStreamBufferStatus(int streamId, camera3_buffer_status_t bufferStatus)
{
    status_t ret = NO_ERROR;

    ret = m_setStreamBufferStatus(streamId, bufferStatus, &m_streamStatusLock);
    if (ret != NO_ERROR) {
        ALOGE("ERR(%s[%d]):[R%d F%d S%d] setCallbackStreamDone is failed.",
                __FUNCTION__, __LINE__, m_key, m_frameCount, streamId);
    }

    return ret;
}

camera3_buffer_status_t ExynosCameraRequest::getStreamBufferStatus(int streamId)
{
    return m_getStreamBufferStatus(streamId, &m_streamStatusLock);
}

ExynosCameraRequestManager::ExynosCameraRequestManager(int cameraId, ExynosCameraParameters *param)
{
    CLOGD("Create-ID(%d)",cameraId);

    setCameraId(cameraId);
    m_parameters = param;
    m_converter = NULL;
    m_callbackOps = NULL;
    m_requestResultKey = 0;
    m_setFlushFlag(false);
    m_resultRenew = 0;
    memset(m_name, 0x00, sizeof(m_name));

    for (int i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
        m_defaultRequestTemplate[i] = NULL;
    }

    m_factoryMap.clear();

    m_notifySequencer = new ExynosCameraCallbackSequencer();
    m_allMetaSequencer = new ExynosCameraCallbackSequencer();

    m_resultCallbackThread = new callbackThread(this, &ExynosCameraRequestManager::m_resultCallbackThreadFunc, "m_resultCallbackThread");

    for (int i = 0; i < EXYNOS_REQUEST_RESULT::CALLBACK_MAX; i++)
        m_lastResultKey[i] = 0;
}

ExynosCameraRequestManager::~ExynosCameraRequestManager()
{
    CLOGD("");

    m_setFlushFlag(false);
    m_resultRenew = 0;

    stopThreadAndInputQ(m_resultCallbackThread, 1, &m_resultCallbackQ);

    if (m_notifySequencer != NULL) {
        m_notifySequencer->flush();
        delete m_notifySequencer;
        m_notifySequencer= NULL;
    }

    if (m_allMetaSequencer != NULL) {
        m_allMetaSequencer->flush();
        delete m_allMetaSequencer;
        m_allMetaSequencer= NULL;
    }

    for (int i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
        if (m_defaultRequestTemplate[i]) {
            free(m_defaultRequestTemplate[i]);
        }
    }

    m_serviceRequests.clear();
    m_runningRequests.clear();

    m_requestFrameCountMap.clear();

    m_factoryMap.clear();

}

status_t ExynosCameraRequestManager::setMetaDataConverter(ExynosCameraMetadataConverter *converter)
{
    status_t ret = NO_ERROR;
    if (m_converter != NULL)
        CLOGD("m_converter is not NULL(%p)", m_converter);

    m_converter = converter;
    return ret;
}

ExynosCameraMetadataConverter* ExynosCameraRequestManager::getMetaDataConverter()
{
    if (m_converter == NULL)
        CLOGD("m_converter is NULL(%p)", m_converter);

    return m_converter;
}

status_t ExynosCameraRequestManager::setRequestsInfo(int key, ExynosCameraFrameFactory *factory)
{
    status_t ret = NO_ERROR;
    if (factory == NULL) {
        CLOGE("m_factory is NULL key(%d) factory(%p)", key, factory);

        ret = INVALID_OPERATION;
        return ret;
    }

    ret = m_pushFactory(key ,factory, &m_factoryMap, &m_factoryMapLock);
    if (ret < 0) {
        CLOGE("m_pushFactory is failed key(%d) factory(%p)", key, factory);

        ret = INVALID_OPERATION;
        return ret;
    }

    return ret;
}

void ExynosCameraRequestManager::clearFrameFactory(void)
{
    m_factoryMapLock.lock();
    m_factoryMap.clear();
    m_factoryMapLock.unlock();
}

ExynosCameraFrameFactory* ExynosCameraRequestManager::getFrameFactory(int key)
{
    status_t ret = NO_ERROR;
    ExynosCameraFrameFactory *factory = NULL;
    if (key < 0) {
        CLOGE("getFrameFactory, type is invalid key(%d)", key);

        ret = INVALID_OPERATION;
        return NULL;
    }

    ret = m_popFactory(key ,&factory, &m_factoryMap, &m_factoryMapLock);
    if (ret < 0) {
        CLOGE("m_popFactory is failed key(%d) factory(%p)", key, factory);

        ret = INVALID_OPERATION;
        return NULL;
    }
    return factory;
}

ExynosCameraRequestSP_sprt_t ExynosCameraRequestManager::registerToServiceList(ExynosCameraRequestSP_sprt_t request)
{
    status_t ret = NO_ERROR;

    ret = m_pushBack(request, &m_serviceRequests, &m_requestLock);
    if (ret < 0){
        CLOGE("request m_pushBack is failed request[R%d]", request->getKey());

        request = NULL;
        return NULL;
    }

    return request;
}

status_t ExynosCameraRequestManager::isPrevRequest()
{
    if (m_previousMeta.isEmpty())
        return BAD_VALUE;
    else
        return OK;
}

status_t ExynosCameraRequestManager::clearPrevRequest()
{
    m_previousMeta.clear();
    return OK;
}

status_t ExynosCameraRequestManager::constructDefaultRequestSettings(int type, camera_metadata_t **request)
{
    Mutex::Autolock l(m_requestLock);

    CLOGD("Type = %d", type);

    if (m_defaultRequestTemplate[type]) {
        *request = m_defaultRequestTemplate[type];
        return OK;
    }

    m_converter->constructDefaultRequestSettings(type, request);

    m_defaultRequestTemplate[type] = *request;

    CLOGD("Registered default request template(%d)", type);
    return OK;
}

status_t ExynosCameraRequestManager::m_pushBack(ExynosCameraRequestSP_sprt_t item, RequestInfoList *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    lock->lock();
    list->push_back(item);
    lock->unlock();
    return ret;
}

status_t ExynosCameraRequestManager::m_popBack(ExynosCameraRequestSP_dptr_t item, RequestInfoList *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    lock->lock();
    if (list->size() > 0) {
        item = list->back();
        list->pop_back();
    } else {
        CLOGE("m_popBack failed, size(%zu)", list->size());
        ret = INVALID_OPERATION;
    }
    lock->unlock();
    return ret;
}

status_t ExynosCameraRequestManager::m_pushFront(ExynosCameraRequestSP_sprt_t item, RequestInfoList *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    lock->lock();
    list->push_front(item);
    lock->unlock();
    return ret;
}

status_t ExynosCameraRequestManager::m_popFront(ExynosCameraRequestSP_dptr_t item, RequestInfoList *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    lock->lock();
    if (list->size() > 0) {
        item = list->front();
        list->pop_front();
    } else {
        CLOGE("m_popFront failed, size(%zu)", list->size());
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequestManager::m_get(uint32_t frameCount,
                                        ExynosCameraRequestSP_dptr_t item,
                                        RequestInfoList *list,
                                        Mutex *lock)
{
    status_t ret = INVALID_OPERATION;
    RequestInfoListIterator iter;
    ExynosCameraRequestSP_sprt_t request = NULL;

    if (item == NULL) {
        CLOGE("item is NULL");
        return BAD_VALUE;
    }

    if (list == NULL) {
        CLOGE("list is NULL");
        return BAD_VALUE;
    }

    if (lock == NULL) {
        CLOGE("lock is NULL");
        return BAD_VALUE;
    }

    lock->lock();
    for (iter = list->begin(); iter != list->end(); ++iter) {
        request = *iter;
        if (request->getKey() == frameCount) {
            ret = NO_ERROR;
            break;
        }
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequestManager::m_push(ExynosCameraRequestSP_sprt_t request, RequestInfoMap *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<RequestInfoMap::iterator,bool> listRet;
    lock->lock();
    listRet = list->insert( pair<uint32_t, ExynosCameraRequestSP_sprt_t>(request->getKey(), request));
    if (listRet.second == false) {
        ret = INVALID_OPERATION;
        CLOGE("m_push failed, request already exist!! Request frameCnt( %d )", request->getFrameCount());
    }
    lock->unlock();

    //m_printAllRequestInfo(list, lock);

    return ret;
}

status_t ExynosCameraRequestManager::m_pop(uint32_t key,
                                            ExynosCameraRequestSP_dptr_t item,
                                            RequestInfoMap *list,
                                            Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<RequestInfoMap::iterator,bool> listRet;
    RequestInfoMapIterator iter;
    ExynosCameraRequestSP_sprt_t request = NULL;

    lock->lock();
    iter = list->find(key);
    if (iter != list->end()) {
        request = iter->second;
        item = request;
        list->erase( iter );
    } else {
        CLOGE("m_pop failed, request is not EXIST Request key(%d)", key);
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequestManager::m_get(uint32_t key,
                                           ExynosCameraRequestSP_dptr_t item,
                                           RequestInfoMap *list,
                                           Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<RequestInfoMap::iterator,bool> listRet;
    RequestInfoMapIterator iter;
    ExynosCameraRequestSP_sprt_t request = NULL;

    lock->lock();
    iter = list->find(key);
    if (iter != list->end()) {
        request = iter->second;
        item = request;
    } else {
        CLOGE("m_pop failed, request is not EXIST Request key(%d)", key);
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    //m_printAllRequestInfo(list, lock);

    return ret;
}

void ExynosCameraRequestManager::m_printAllServiceRequestInfo(void)
{
    Mutex::Autolock l(m_requestLock);

    RequestInfoListIterator iter;
    ExynosCameraRequestSP_sprt_t request;
    camera3_capture_request_t *serviceRequest;

    for (iter = m_serviceRequests.begin(); iter != m_serviceRequests.end(); ++iter) {
        request = *iter;
        serviceRequest = request->getServiceRequest();
        CLOGI("key(%d), serviceFrameCount(%d), (%p) frame_number(%d), outputNum(%d)",
                request->getKey(),
                request->getFrameCount(),
                serviceRequest,
                serviceRequest->frame_number,
                serviceRequest->num_output_buffers);

    }
}

void ExynosCameraRequestManager::m_printAllRequestInfo(RequestInfoMap *map, Mutex *lock)
{
    RequestInfoMapIterator iter;
    ExynosCameraRequestSP_sprt_t request = NULL;
    ExynosCameraRequestSP_sprt_t item = NULL;
    camera3_capture_request_t *serviceRequest = NULL;

    lock->lock();
    iter = map->begin();

    while(iter != map->end()) {
        request = iter->second;
        item = request;

        serviceRequest = item->getServiceRequest();

        CLOGI("key(%d), serviceFrameCount(%d), (%p) frame_number(%d), outputNum(%d)",
            request->getKey(),
            request->getFrameCount(),
            serviceRequest,
            serviceRequest->frame_number,
            serviceRequest->num_output_buffers);

        iter++;
    }
    lock->unlock();
}

status_t ExynosCameraRequestManager::m_pushFactory(int key,
                                                    ExynosCameraFrameFactory* item,
                                                    FrameFactoryMap *list,
                                                    Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<FrameFactoryMap::iterator,bool> listRet;
    lock->lock();
    listRet = list->insert(pair<uint32_t, ExynosCameraFrameFactory*>(key, item));
    if (listRet.second == false) {
        ret = INVALID_OPERATION;
        CLOGE("m_push failed, request already exist!! Request key( %d )", key);
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequestManager::m_popFactory(int key, ExynosCameraFrameFactory** item, FrameFactoryMap *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<FrameFactoryMap::iterator,bool> listRet;
    FrameFactoryMapIterator iter;
    ExynosCameraFrameFactory *factory = NULL;

    lock->lock();
    iter = list->find(key);
    if (iter != list->end()) {
        factory = iter->second;
        *item = factory;
        list->erase( iter );
    } else {
        CLOGE("m_pop failed, factory is not EXIST Request key( %d )", key);
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    return ret;
}

status_t ExynosCameraRequestManager::m_getFactory(int key, ExynosCameraFrameFactory** item, FrameFactoryMap *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    pair<FrameFactoryMap::iterator,bool> listRet;
    FrameFactoryMapIterator iter;
    ExynosCameraFrameFactory *factory = NULL;
    lock->lock();
    iter = list->find(key);
    if (iter != list->end()) {
        factory = iter->second;
        *item = factory;
    } else {
        CLOGE("m_pop failed, request is not EXIST Request key( %d )", key);
        ret = INVALID_OPERATION;
    }
    lock->unlock();

    return ret;
}

uint32_t ExynosCameraRequestManager::getAllRequestCount(void)
{
    Mutex::Autolock l(m_requestLock);
    return m_serviceRequests.size() + m_runningRequests.size();
}

uint32_t ExynosCameraRequestManager::getServiceRequestCount(void)
{
    Mutex::Autolock lock(m_requestLock);
    return m_serviceRequests.size();
}

uint32_t ExynosCameraRequestManager::getRunningRequestCount(void)
{
    Mutex::Autolock lock(m_requestLock);
    return m_runningRequests.size();
}

ExynosCameraRequestSP_sprt_t ExynosCameraRequestManager::eraseFromServiceList(void)
{
    status_t ret = NO_ERROR;
    ExynosCameraRequestSP_sprt_t request = NULL;

    ret = m_popFront(request, &m_serviceRequests, &m_requestLock);
    if (ret < 0){
        CLOGE("request m_popFront is failed request");
        ret = INVALID_OPERATION;
        return NULL;
    }

    return request;
}

status_t ExynosCameraRequestManager::registerToRunningList(ExynosCameraRequestSP_sprt_t request_in)
{
    status_t ret = NO_ERROR;

    ret = m_push(request_in, &m_runningRequests, &m_requestLock);
    if (ret < 0){
        CLOGE("request m_push is failed request");
        ret = INVALID_OPERATION;
        return ret;
    }

    ret = m_increasePipelineDepth(&m_runningRequests, &m_requestLock);
    if (ret != NO_ERROR)
        CLOGE("Failed to increase the pipeline depth");

    m_notifySequencer->pushToRunningKeyList(request_in->getKey());
    m_allMetaSequencer->pushToRunningKeyList(request_in->getKey());

    return ret;
}

status_t ExynosCameraRequestManager::m_removeFromRunningList(uint32_t requestKey)
{
    status_t ret = NO_ERROR;
    ExynosCameraRequestSP_sprt_t request = NULL;

    ret = m_pop(requestKey, request, &m_runningRequests, &m_requestLock);
    if (ret < 0){
        ret = INVALID_OPERATION;
        CLOGE("request m_popFront is failed request");
    }

    if (m_getFlushFlag() == false) {
        uint32_t key = 0;
        ret = m_popKey(&key, request->getFrameCount());
        if (ret < NO_ERROR) {
            CLOGE("Failed to m_popKey. frameCount %d", request->getFrameCount());
            return INVALID_OPERATION;
        }
    }

    return ret;
}

ExynosCameraRequestSP_sprt_t ExynosCameraRequestManager::getRunningRequest(uint32_t frameCount)
{
    status_t ret = NO_ERROR;
    uint32_t key = 0;
    ExynosCameraRequestSP_sprt_t request = NULL;

    ret = m_getKey(&key, frameCount);
    if (ret < NO_ERROR) {
        CLOGE("Failed to m_popKey. frameCount %d", frameCount);
        return NULL;
    }

    ret = m_get(key, request, &m_runningRequests, &m_requestLock);
    if (ret < 0) {
        ret = INVALID_OPERATION;
        CLOGE("request m_popFront is failed request");
    }

    return request;
}

void ExynosCameraRequestManager::notifyDeviceError(void)
{
    camera3_notify_msg_t notifyMsg;

    memset(&notifyMsg, 0, sizeof(notifyMsg));

    notifyMsg.type = CAMERA3_MSG_ERROR;
    notifyMsg.message.error.error_code = CAMERA3_MSG_ERROR_DEVICE;

    m_callbackOpsNotify(&notifyMsg);
}

status_t ExynosCameraRequestManager::flush()
{
    status_t ret = NO_ERROR;
    uint32_t requestKey = 0;
    ExynosCameraRequestSP_sprt_t request = NULL;
    ResultRequest resultRequest = NULL;

    camera3_notify_msg_t *notifyMsg = NULL;
    camera3_capture_result_t *requestResult = NULL;
    camera3_stream_buffer_t *streamBuffer = NULL;
    const camera3_stream_buffer_t *outputBuffer = NULL;

    CameraMetadata resultMeta;

    int32_t streamId = 0;

    uint32_t bufferCnt = 0;
    ExynosCameraStream *stream = NULL;

    EXYNOS_REQUEST_RESULT::TYPE cbType = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;

    m_setFlushFlag(true);
    m_resultRenew = 0;

    m_resultCallbackThread->requestExitAndWait();
    m_resultCallbackQ.release();

    m_callbackFlushTimer.start();

    CLOGD("IN+++");
    CLOGD("AllRequestCount(%d), ServiceRequestCount(%d), RunningRequestCount(%d)",
            getAllRequestCount(), getServiceRequestCount(), getRunningRequestCount());

    do {
        /*
         * If the flush is operated, the frameCount in request may be an inavlid value.
         * Because, the request before matched with frameCount will be transfer to RunningList from ServiceList.
         */

        for (uint32_t i = 0; i < getServiceRequestCount(); i++) {
            eraseFromServiceList();
        }

        while (m_runningRequests.begin() != m_runningRequests.end()) {
            RequestInfoMapIterator requestMapIter = m_runningRequests.begin();

            request = requestMapIter->second;
            requestKey = request->getKey();

            notifyMsg = NULL;
            cbType = EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ONLY;
            if (request->getCallbackDone(cbType) == false) {
                resultRequest = createResultRequest(requestKey, request->getFrameCount(), cbType);
                if (resultRequest == NULL) {
                    CLOGE("[R%d] createResultRequest fail. Notify Callback", request->getKey());
                    continue;
                }

                notifyMsg = resultRequest->getNotifyMsg();
                if (notifyMsg == NULL) {
                    CLOGE("[R%d] getNotifyResult fail. Notify Callback", request->getKey());
                    continue;
                }

                request->setRequestState(EXYNOS_REQUEST::STATE_ERROR);
                request->setSkipMetaResult(true);

                notifyMsg->type = CAMERA3_MSG_ERROR;
                notifyMsg->message.error.frame_number = requestKey;

                if (request->getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA) == true
                        || request->getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_BUFFER_ONLY) == true) {
                    notifyMsg->message.error.error_code = CAMERA3_MSG_ERROR_RESULT;
                } else {
                    notifyMsg->message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
                }

                m_notifyErrorCallback(request, resultRequest);
                request->setCallbackDone(cbType, true);
            }

            requestResult = NULL;
            cbType = EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA;
            if (request->getCallbackDone(cbType) == false) {
                resultRequest = createResultRequest(requestKey, request->getFrameCount(), cbType);
                if (resultRequest == NULL) {
                    CLOGE("[R%d] createResultRequest fail. 3AA_META", request->getKey());
                    continue;
                }

                requestResult = resultRequest->getCaptureResult();
                if (requestResult == NULL) {
                    CLOGE("[R%d] getCaptureResult fail. 3AA_META", request->getKey());
                    continue;
                }

                request->setRequestLock();
                resultMeta = request->get3AAResultMeta();
                request->setRequestUnlock();

                requestResult->frame_number = requestKey;
                requestResult->result = resultMeta.release();
                requestResult->num_output_buffers = 0;
                requestResult->output_buffers = NULL;
                requestResult->input_buffer = NULL;
                requestResult->partial_result = 1;

                m_partialMetaCallback(request, resultRequest);
            }

            requestResult = NULL;
            cbType = EXYNOS_REQUEST_RESULT::CALLBACK_ALL_RESULT;
            if (request->getCallbackDone(cbType) == false) {
                resultRequest = createResultRequest(requestKey, request->getFrameCount(), cbType);
                if (resultRequest == NULL) {
                    CLOGE("[R%d] createResultRequest fail. 3AA_META", request->getKey());
                    continue;
                }

                requestResult = resultRequest->getCaptureResult();
                if (requestResult == NULL) {
                    CLOGE("[R%d] getCaptureResult fail. 3AA_META", request->getKey());
                    continue;
                }

                request->setRequestLock();
                request->updatePipelineDepth();
                resultMeta = *(request->getServiceMeta());
                request->setRequestUnlock();

                requestResult->frame_number = requestKey;
                requestResult->result = resultMeta.release();
                requestResult->num_output_buffers = 0;
                requestResult->output_buffers = NULL;
                requestResult->input_buffer = NULL;
                requestResult->partial_result = 2;

                m_allMetaCallback(request, resultRequest);
            }

            cbType = EXYNOS_REQUEST_RESULT::CALLBACK_BUFFER_ONLY;

            outputBuffer = NULL;
            bufferCnt = request->getNumOfOutputBuffer();
            outputBuffer = request->getOutputBuffers();
            for(uint32_t i = 0 ; i < bufferCnt ; i++) {
                stream = static_cast<ExynosCameraStream*>(outputBuffer[i].stream->priv);
                stream->getID(&streamId);

                requestResult = NULL;
                if (request->getCallbackStreamDone(streamId) == false) {
                    resultRequest = createResultRequest(requestKey, request->getFrameCount(), cbType);
                    if (resultRequest == NULL) {
                        CLOGE("[R%d S%d] createResultRequest fail.", request->getKey(), streamId);
                        continue;
                    }

                    requestResult = resultRequest->getCaptureResult();
                    if (requestResult == NULL) {
                        CLOGE("[R%d S%d] getCaptureResult fail.", request->getKey(), streamId);
                        continue;
                    }

                    streamBuffer = resultRequest->getStreamBuffer();
                    if (streamBuffer == NULL) {
                        CLOGE("[R%d S%d] getStreamBuffer fail.", request->getKey(), streamId);

                        /* Continue to handle other streams */
                        continue;
                    }

                    ret = stream->getStream(&(streamBuffer->stream));
                    if (ret != NO_ERROR) {
                        CLOGE("[R%d S%d]Failed to getStream.", request->getKey(), streamId);

                        /* Continue to handle other streams */
                        continue;
                    }

                    streamBuffer->buffer = outputBuffer[i].buffer;
                    streamBuffer->acquire_fence = -1;

                    if (request->getAcquireFenceDone(streamBuffer->buffer) == true) {
                        streamBuffer->release_fence = -1;
                    } else {
                        int err = sync_wait(outputBuffer[i].acquire_fence, 1 /* msec */);
                        if (err >= 0) {
                            streamBuffer->release_fence = outputBuffer[i].acquire_fence;
                        } else {
                            streamBuffer->release_fence = -1;
                        }
                    }
                    CLOGV("[R%d S%d] acquire_fence(%d), release_fence(%d)",
                            request->getKey(), streamId, streamBuffer->acquire_fence, streamBuffer->release_fence);

                    streamBuffer->status = CAMERA3_BUFFER_STATUS_ERROR;

                    /* construct result for service */
                    requestResult->frame_number = requestKey;
                    requestResult->result = NULL;
                    requestResult->num_output_buffers = 1;
                    requestResult->output_buffers = streamBuffer;
                    requestResult->input_buffer = request->getInputBuffer();
                    requestResult->partial_result = 0;

                    m_bufferOnlyCallback(request, resultRequest);
                }
            }
        }
    } while (getServiceRequestCount() > 0);

    m_serviceRequests.clear();
    m_runningRequests.clear();

    m_requestFrameCountMap.clear();

    m_callbackFlushTimer.stop();

    long long FlushTime = m_callbackFlushTimer.durationMsecs();
    CLOGV("flush time(%lld)", FlushTime);

    m_setFlushFlag(false);

    stopThreadAndInputQ(m_resultCallbackThread, 1, &m_resultCallbackQ);

    if (m_notifySequencer != NULL) {
        m_notifySequencer->flush();
    }

    if (m_allMetaSequencer != NULL) {
        m_allMetaSequencer->flush();
    }

    /* dump */
    if (getAllRequestCount() > 0)
        dump();

    CLOGD(" OUT---");

    return ret;
}

status_t ExynosCameraRequestManager::m_getKey(uint32_t *key, uint32_t frameCount)
{
    status_t ret = NO_ERROR;
    RequestFrameCountMapIterator iter;

    m_requestFrameCountMapLock.lock();
    iter = m_requestFrameCountMap.find(frameCount);
    if (iter != m_requestFrameCountMap.end()) {
        *key = iter->second;
    } else {
        CLOGE("get request key is failed. request for framecount(%d) is not EXIST", frameCount);
        ret = INVALID_OPERATION;
    }
    m_requestFrameCountMapLock.unlock();

    return ret;
}

status_t ExynosCameraRequestManager::m_popKey(uint32_t *key, uint32_t frameCount)
{
    status_t ret = NO_ERROR;
    RequestFrameCountMapIterator iter;

    m_requestFrameCountMapLock.lock();
    iter = m_requestFrameCountMap.find(frameCount);
    if (iter != m_requestFrameCountMap.end()) {
        *key = iter->second;
        m_requestFrameCountMap.erase(iter);
    } else {
        CLOGE("get request key is failed. request for framecount(%d) is not EXIST", frameCount);
        ret = INVALID_OPERATION;
    }
    m_requestFrameCountMapLock.unlock();

    return ret;
}

uint32_t ExynosCameraRequestManager::m_generateResultKey()
{
    m_requestResultKeyLock.lock();
    uint32_t key = m_requestResultKey++;
    m_requestResultKeyLock.unlock();
    return key;
}

ResultRequest ExynosCameraRequestManager::createResultRequest(uint32_t requestKey,
                                                              uint32_t frameCount,
                                                              EXYNOS_REQUEST_RESULT::TYPE type)
{
    ResultRequest result;

    result = new ExynosCameraRequestResult(m_generateResultKey(), requestKey, frameCount, type);

    return result;
}

status_t ExynosCameraRequestManager::setCallbackOps(const camera3_callback_ops *callbackOps)
{
    status_t ret = NO_ERROR;
    m_callbackOps = callbackOps;
    return ret;
}

status_t ExynosCameraRequestManager::setFrameCount(uint32_t frameCount, uint32_t requestKey)
{
    status_t ret = NO_ERROR;
    pair<RequestFrameCountMapIterator, bool> listRet;
    ExynosCameraRequestSP_sprt_t request = NULL;

    m_requestFrameCountMapLock.lock();
    listRet = m_requestFrameCountMap.insert(pair<uint32_t, uint32_t>(frameCount, requestKey));
    if (listRet.second == false) {
        ret = INVALID_OPERATION;
        CLOGE("Failed, requestKey(%d) already exist!!", frameCount);
        m_requestFrameCountMapLock.unlock();
        return ret;
    }
    m_requestFrameCountMapLock.unlock();

    ret = m_get(requestKey, request, &m_runningRequests, &m_requestLock);
    if (ret < 0)
        CLOGE("m_get is failed. requestKey(%d)", requestKey);

    request->setFrameCount(frameCount);

    return ret;
}

// Count number of invocation and print FPS for every 30 frames.
void ExynosCameraRequestManager::m_debugCallbackFPS() {
#ifdef CALLBACK_FPS_CHECK
    m_callbackFrameCnt++;
    if(m_callbackFrameCnt % 30 == 0) {
        // Initial invocation
        m_callbackDurationTimer.start();
    } else if(m_callbackFrameCnt % 30 == 29) {
        m_callbackDurationTimer.stop();
        long long durationTime = m_callbackDurationTimer.durationMsecs();

        CLOGI("CALLBACK_FPS_CHECK, duration %lld", durationTime);
        //m_callbackFrameCnt = 0;
    }
#endif
}

status_t ExynosCameraRequestManager::m_sendCallbackResult(ResultRequest result)
{
    status_t ret = NO_ERROR;
    camera3_capture_result_t *capture_result = NULL;
    camera3_notify_msg_t *notify_msg = NULL;
    ExynosCameraRequestSP_sprt_t request = NULL;

    ret = m_get(result->getRequestKey(), request, &m_runningRequests, &m_requestLock);
    if (ret < NO_ERROR) {
        CLOGE("[R%d F%d] m_get is failed.",
                result->getRequestKey(), result->getFrameCount());
        return ret;
    }

    CLOGV("[R%d F%d T%d] m_sendCallbackResult",
            result->getRequestKey(), result->getFrameCount(), result->getType());

    switch(result->getType()){
    case EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ONLY:
        notify_msg = result->getNotifyMsg();
        if (request->getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ERROR) == true) {
            CLOGV("[R%d] skip NOTIFY_SHUTTER.", result->getRequestKey());
        } else {
            m_callbackOpsNotify(notify_msg);
        }
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_BUFFER_ONLY:
        capture_result = result->getCaptureResult();
        m_callbackOpsCaptureResult(capture_result);
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA:
    case EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_SHUTTER:
        capture_result = result->getCaptureResult();

        /* Due to the limitations of the service, can not update the meta callback if update the notify error. */
        if (request->getSkipMetaResult() == true) {
            CLOGV("[R%d] skip CALLBACK_PARTIAL_3AA.", result->getRequestKey());
        } else {
            m_callbackOpsCaptureResult(capture_result);
        }

        if (capture_result->result != NULL)
            free((camera_metadata_t *)(capture_result->result));

        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_ALL_RESULT:
        capture_result = result->getCaptureResult();

        /* Due to the limitations of the service, can not update the meta callback if update the notify error. */
        if (request->getSkipMetaResult() == true) {
            CLOGV("[R%d] skip CALLBACK_ALL_RESULT.", result->getRequestKey());
        } else {
            m_callbackOpsCaptureResult(capture_result);
        }

        if (capture_result->result != NULL)
            free((camera_metadata_t *)(capture_result->result));
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ERROR:
        notify_msg = result->getNotifyMsg();
        m_callbackOpsNotify(notify_msg);
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_INVALID:
    default:
        ret = BAD_VALUE;
        CLOGE("[R%d F%d T%d] callback type have INVALID value ",
                 result->getRequestKey(), result->getFrameCount(), result->getType());
        break;
    }

    return ret;
}

status_t ExynosCameraRequestManager::m_callbackOpsCaptureResult(camera3_capture_result_t *result)
{
    status_t ret = NO_ERROR;

#ifdef DEBUG_STREAM_CONFIGURATIONS
    CLOGD("DEBUG_STREAM_CONFIGURATIONS:frame number(%d), #out(%d)",
             result->frame_number, result->num_output_buffers);
#else
    CLOGV("frame number(%d), #out(%d)",
             result->frame_number, result->num_output_buffers);
#endif

    m_callbackOps->process_capture_result(m_callbackOps, result);
    return ret;
}

status_t ExynosCameraRequestManager::m_callbackOpsNotify(camera3_notify_msg_t *msg)
{
    status_t ret = NO_ERROR;

    switch (msg->type) {
    case CAMERA3_MSG_ERROR:
        CLOGW("msg frame(%d) type(%d) errorCode(%d)",
                 msg->message.error.frame_number, msg->type, msg->message.error.error_code);
        m_callbackOps->notify(m_callbackOps, msg);
        break;
    case CAMERA3_MSG_SHUTTER:
        CLOGV("msg frame(%d) type(%d) timestamp(%llu)",
                 msg->message.shutter.frame_number, msg->type, (unsigned long long)msg->message.shutter.timestamp);
        m_callbackOps->notify(m_callbackOps, msg);
        break;
    default:
        CLOGE("Msg type is invalid (%d)", msg->type);
        ret = BAD_VALUE;
        break;
    }
    return ret;
}

/* Increase the pipeline depth value from each request in running request map */
status_t ExynosCameraRequestManager::m_increasePipelineDepth(RequestInfoMap *map, Mutex *lock)
{
    status_t ret = NO_ERROR;
    RequestInfoMapIterator requestIter;
    ExynosCameraRequestSP_sprt_t request = NULL;

    lock->lock();
    if (map->size() < 1) {
        CLOGV("map is empty. Skip to increase the pipeline depth");
        ret = NO_ERROR;
        goto func_exit;
    }

    requestIter = map->begin();
    while (requestIter != map->end()) {
        request = requestIter->second;

        request->increasePipelineDepth();
        requestIter++;
    }

func_exit:
    lock->unlock();
    return ret;
}

status_t ExynosCameraRequestManager::pushResultRequest(ResultRequest result)
{
    if (m_resultCallbackThread->isRunning() == false) {
        m_resultCallbackThread->run();
    }

    if (result == NULL) {
        CLOGE("Result is NULL");
        return BAD_VALUE;
    }

    m_resultCallbackQ.pushProcessQ(&result);

    return NO_ERROR;
}

void ExynosCameraRequestManager::m_setFlushFlag(bool flag)
{
    Mutex::Autolock l(m_flushLock);
    m_flushFlag = flag;
}

bool ExynosCameraRequestManager::m_getFlushFlag(void)
{
    Mutex::Autolock l(m_flushLock);
    return m_flushFlag;
}

int32_t ExynosCameraRequestManager::getResultRenew(void)
{
    return m_resultRenew;
}

void ExynosCameraRequestManager::incResultRenew(void)
{
    if (m_getFlushFlag() == true) {
        CLOGV("flush flag is set. Do not increase the result renew count");
    } else {
        m_resultRenew++;
    }
}

void ExynosCameraRequestManager::resetResultRenew(void)
{
    m_resultRenew = 0;
}

void ExynosCameraRequestManager::dump(void)
{
    CLOGD("AllRequestCount(%d), ServiceRequestCount(%d), RunningRequestCount(%d)",
            getAllRequestCount(), getServiceRequestCount(), getRunningRequestCount());

    CLOGD("----- Last Result Key -----");
    for (int i = 0; i < EXYNOS_REQUEST_RESULT::CALLBACK_MAX; i++)
        CLOGI("Type[%d] = Last Key(%d)", i, m_lastResultKey[i]);

    CLOGD("----- All Remained Request Info (m_serviceRequests-----");
    m_printAllServiceRequestInfo();

    CLOGD("----- All Remained Request Info (m_runningRequests-----");
    m_printAllRequestInfo(&m_runningRequests, &m_requestLock);
}

bool ExynosCameraRequestManager::m_requestDeleteFunc(ExynosCameraRequestSP_sprt_t curRequest)
{
    status_t ret = NO_ERROR;

    if (curRequest == NULL) {
        CLOGE("Request is NULL");
        ret = INVALID_OPERATION;
        return ret;
    }

    CLOGV("[R%d] Try to delete request. RunningRequestList size(%d)",
        curRequest->getKey(), getRunningRequestCount());

    if (curRequest->isComplete() &&
        (int)curRequest->getNumOfOutputBuffer() == curRequest->getCompleteBufferCount()) {
        CLOGV("[R%d] m_removeFromRunningList.", curRequest->getKey());
        m_removeFromRunningList(curRequest->getKey());
    } else {
        CLOGV("[R%d] Request is not deleted yet.", curRequest->getKey());
    }

    return ret;
}

bool ExynosCameraRequestManager::m_resultCallbackThreadFunc(void)
{
    status_t ret = NO_ERROR;

    ret = m_resultCallback();
    if (ret != NO_ERROR) {
        CLOGE("ResultCallback fail, ret(%d)", ret);
        /* TODO: doing exception handling */
    } else {
        m_resultRenew = 0;
    }

    return true;
}

bool ExynosCameraRequestManager::m_resultCallback(void)
{
    CLOGV("-IN-");
    status_t ret = NO_ERROR;

    ExynosCameraRequestSP_sprt_t curRequest = NULL;
    ResultRequest result = NULL;

    ret = m_resultCallbackQ.waitAndPopProcessQ(&result);
    if (ret == TIMED_OUT) {
        CLOGV("resultCallbackQ wait timeout");
        return ret;
    } else if (ret != NO_ERROR) {
        CLOGE("resultCallbackQ wait and pop fail, ret(%d)", ret);
        /* TODO: doing exception handling */
        return ret;
    }

    if (result == NULL) {
        CLOGE("result is NULL");
        return BAD_VALUE;
    }

    ret = m_get(result->getRequestKey(), curRequest, &m_runningRequests, &m_requestLock);
    if (ret < NO_ERROR) {
        CLOGE("[R%d T%d] m_get is failed.", result->getRequestKey(), result->getType());
        return ret;
    }

    CLOGV("[R%d T%d] resultCallbackQ(%d)",
            curRequest->getKey(), result->getType(), m_resultCallbackQ.getSizeOfProcessQ());

    if (result->getType() != EXYNOS_REQUEST_RESULT::CALLBACK_INVALID)
        m_lastResultKey[result->getType()] = curRequest->getKey();

    switch(result->getType()){
    case EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ONLY:
        m_notifyCallback(curRequest, result);
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_BUFFER_ONLY:
        m_bufferOnlyCallback(curRequest, result);
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA:
    case EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_SHUTTER:
        m_partialMetaCallback(curRequest, result);
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_ALL_RESULT:
        m_allMetaCallback(curRequest, result);
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_NOTIFY_ERROR:
        m_notifyErrorCallback(curRequest, result);
        break;
    case EXYNOS_REQUEST_RESULT::CALLBACK_INVALID:
    default:
        CLOGE("[R%d T%d] callback type is INVALID.", curRequest->getKey(), result->getType());
        break;
    }

    CLOGV("-OUT-");

    return ret;
}

bool ExynosCameraRequestManager::m_notifyCallback(ExynosCameraRequestSP_sprt_t curRequest, ResultRequest result)
{
    CLOGV("-IN-");
    status_t ret = NO_ERROR;
    uint32_t wishNotifyCount = 0;

    EXYNOS_REQUEST_RESULT::TYPE cbType = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;

    cbType = result->getType();

    if (curRequest == NULL) {
        CLOGE("request is NULL");
        ret = INVALID_OPERATION;
        return ret;
    }

    wishNotifyCount = m_notifySequencer->getFrontKeyFromRunningKeyList();

    CLOGV("[R%d W%d] NotifyCallback state(%d)", curRequest->getKey(), wishNotifyCount,
            curRequest->getCallbackDone(cbType));

    if (curRequest->getCallbackDone(cbType) == false) {
        if (curRequest->getKey() == wishNotifyCount) {

            m_sendCallbackResult(result);
            curRequest->setCallbackDone(cbType, true);

            m_notifySequencer->deleteRunningKey(wishNotifyCount);

            m_requestDeleteFunc(curRequest);
        } else if (curRequest->getKey() > wishNotifyCount) {
            CLOGV("[R%d W%d] Notify result is pushed back in resultCallbackQ(%d)",
                    curRequest->getKey(), wishNotifyCount, m_resultCallbackQ.getSizeOfProcessQ());

            this->pushResultRequest(result);
        }
    } else {
        CLOGW("[R%d W%d] Notify result is already sent", curRequest->getKey(), wishNotifyCount);
    }

    CLOGV("-END-");

    return ret;
}

bool ExynosCameraRequestManager::m_partialMetaCallback(ExynosCameraRequestSP_sprt_t curRequest, ResultRequest result)
{
    CLOGV("-IN-");
    status_t ret = NO_ERROR;

    EXYNOS_REQUEST_RESULT::TYPE cbType = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;

    cbType = result->getType();

    if (curRequest == NULL) {
        CLOGE("request is NULL");
        ret = INVALID_OPERATION;
        return ret;
    }

    CLOGV("[R%d] 3aaMetaCallback state(%d)", curRequest->getKey(), curRequest->getCallbackDone(cbType));

    if (curRequest->getCallbackDone(cbType) == false) {
        m_sendCallbackResult(result);
        curRequest->setCallbackDone(cbType, true);

        m_requestDeleteFunc(curRequest);
    } else {
        CLOGW("[R%d] 3aaMeta result is already sent", curRequest->getKey());
    }

    CLOGV("-END-");

    return ret;
}

bool ExynosCameraRequestManager::m_allMetaCallback(ExynosCameraRequestSP_sprt_t curRequest, ResultRequest result)
{
    CLOGV("-IN-");
    status_t ret = NO_ERROR;
    uint32_t wishAllMetaCount = 0;

    EXYNOS_REQUEST_RESULT::TYPE cbType = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;

    cbType = result->getType();

    if (curRequest == NULL) {
        CLOGE("request is NULL");
        ret = INVALID_OPERATION;
        return ret;
    }

    wishAllMetaCount = m_allMetaSequencer->getFrontKeyFromRunningKeyList();

    CLOGV("[R%d W%d] AllMetaCallback state(%d)", curRequest->getKey(), wishAllMetaCount,
            curRequest->getCallbackDone(cbType));

    if (curRequest->getCallbackDone(cbType) == false) {
        if (curRequest->getKey() == wishAllMetaCount
            && curRequest->getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA) == true) {
            m_sendCallbackResult(result);
            curRequest->setCallbackDone(cbType, true);

            m_allMetaSequencer->deleteRunningKey(wishAllMetaCount);

            m_requestDeleteFunc(curRequest);
        } else if (curRequest->getKey() > wishAllMetaCount
                   || curRequest->getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA) == false) {
            CLOGV("[R%d W%d 3S%d]. AllMeta result is pushed back in resultCallbackQ(%d)",
                curRequest->getKey(), wishAllMetaCount,
                curRequest->getCallbackDone(EXYNOS_REQUEST_RESULT::CALLBACK_PARTIAL_3AA),
                m_resultCallbackQ.getSizeOfProcessQ());

            this->pushResultRequest(result);
        }
    } else {
        CLOGW("[R%d W%d] AllMeta result is already sent", curRequest->getKey(), wishAllMetaCount);
    }

    CLOGV("-END-");

    return ret;
}

bool ExynosCameraRequestManager::m_bufferOnlyCallback(ExynosCameraRequestSP_sprt_t curRequest, ResultRequest result)
{
    CLOGV("-IN-");
    status_t ret = NO_ERROR;

    camera3_stream_t *resultStream = NULL;;
    camera3_stream_buffer_t *streamBuffer = NULL;
    ExynosCameraStream *privStreamInfo = NULL;
    int32_t resultStreamId = -1;

    EXYNOS_REQUEST_RESULT::TYPE cbType = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;

    cbType = result->getType();

    if (curRequest == NULL) {
        CLOGE("request is NULL");
        ret = INVALID_OPERATION;
        return ret;
    }

    streamBuffer = result->getStreamBuffer();
    resultStream = streamBuffer->stream;
    privStreamInfo = static_cast<ExynosCameraStream*>(resultStream->priv);
    privStreamInfo->getID(&resultStreamId);

    CLOGV("[R%d S%d(%d)] BufferOnlyCallback state(%d)",
            curRequest->getKey(), resultStreamId, resultStreamId % HAL_STREAM_ID_MAX,
            curRequest->getCallbackDone(cbType));

    if (curRequest->getCallbackStreamDone(resultStreamId) == false) {
        m_sendCallbackResult(result);
        curRequest->increaseCompleteBufferCount();
        curRequest->setCallbackStreamDone(resultStreamId, true);

        m_requestDeleteFunc(curRequest);
    } else {
        CLOGW("[R%d S%d(%d)] BufferOnly result is already sent.",
            curRequest->getKey(), resultStreamId, resultStreamId % HAL_STREAM_ID_MAX);
    }

    CLOGV("-END-");

    return ret;
}

bool ExynosCameraRequestManager::m_notifyErrorCallback(ExynosCameraRequestSP_sprt_t curRequest, ResultRequest result)
{
    CLOGV("-IN-");
    status_t ret = NO_ERROR;

    EXYNOS_REQUEST_RESULT::TYPE cbType = EXYNOS_REQUEST_RESULT::CALLBACK_INVALID;

    cbType = result->getType();

    if (curRequest == NULL) {
        CLOGE("request is NULL");
        ret = INVALID_OPERATION;
        return ret;
    }

    CLOGV("[R%d F%d] notifyErrorCallback state(%d)",
            curRequest->getKey(), curRequest->getFrameCount(),
            curRequest->getCallbackDone(cbType));

    if ((int) curRequest->getNumOfOutputBuffer() > curRequest->getCompleteBufferCount()) {
        curRequest->setSkipMetaResult(true);
    }

    m_sendCallbackResult(result);
    curRequest->setCallbackDone(cbType, true);

    m_requestDeleteFunc(curRequest);

    CLOGV("-END-");

    return ret;
}

status_t ExynosCameraRequestManager::waitforRequestflush()
{
    int count = 0;

    CLOGD("m_serviceRequest size(%d) m_runningRequest size(%d)",
           (int)m_serviceRequests.size(), (int)m_runningRequests.size());

    while (true) {
        if (m_serviceRequests.size() == 0 && m_runningRequests.size() == 0)
            break;

        usleep(50000);

        if (count++ == 200)
            break;
    }

    if (count > 200) {
        CLOGW("m_serviceRequest size(%d) m_runningRequest size(%d), count(%d)",
               (int)m_serviceRequests.size(), (int)m_runningRequests.size(), count);
    } else {
        CLOGD("Done : count(%d)", count);
    }

    return 0;
}

ExynosCameraCallbackSequencer::ExynosCameraCallbackSequencer()
{
    m_init();
}

ExynosCameraCallbackSequencer::~ExynosCameraCallbackSequencer()
{
    if (m_runningRequestKeys.size() > 0) {
        CLOGE2("destructor size is not ZERO(%zu)",
                 m_runningRequestKeys.size());
    }

    m_deinit();
}

uint32_t ExynosCameraCallbackSequencer::popFromRunningKeyList()
{
    status_t ret = NO_ERROR;
    uint32_t obj;

    obj = m_pop(EXYNOS_LIST_OPER::SINGLE_FRONT, &m_runningRequestKeys, &m_requestCbListLock);
    if (ret < 0){
        CLOGE2("m_pop failed");
        return 0;
    }

    return obj;
}

uint32_t ExynosCameraCallbackSequencer::getFrontKeyFromRunningKeyList()
{
    status_t ret = NO_ERROR;
    uint32_t obj;

    obj = m_get(EXYNOS_LIST_OPER::SINGLE_FRONT, &m_runningRequestKeys, &m_requestCbListLock);
    if (ret < 0){
        CLOGE2("m_get failed");
        return 0;
    }

    return obj;
}

status_t ExynosCameraCallbackSequencer::pushToRunningKeyList(uint32_t key)
{
    status_t ret = NO_ERROR;

    ret = m_push(EXYNOS_LIST_OPER::SINGLE_BACK, key, &m_runningRequestKeys, &m_requestCbListLock);
    if (ret < 0){
        CLOGE2("m_push failed, key(%d)", key);
    }

    return ret;
}

uint32_t ExynosCameraCallbackSequencer::getRunningKeyListSize()
{
    Mutex::Autolock lock(m_requestCbListLock);
    return m_runningRequestKeys.size();
}

status_t ExynosCameraCallbackSequencer::getRunningKeyList(CallbackListkeys *list)
{
    status_t ret = NO_ERROR;

    list->clear();

    m_requestCbListLock.lock();
    std::copy(m_runningRequestKeys.begin(), m_runningRequestKeys.end(), std::back_inserter(*list));
    m_requestCbListLock.unlock();
    return ret;
}

status_t ExynosCameraCallbackSequencer::deleteRunningKey(uint32_t key)
{
    status_t ret = NO_ERROR;

    ret = m_delete(key, &m_runningRequestKeys, &m_requestCbListLock);
    if (ret < 0){
        CLOGE2("m_delete failed, key(%d)", key);
    }

    return ret;
}

void ExynosCameraCallbackSequencer::dumpList()
{
    CallbackListkeysIter iter;
    CallbackListkeys *list = &m_runningRequestKeys;

    m_requestCbListLock.lock();

    if (list->size() > 0) {
        for (iter = list->begin(); iter != list->end();) {
            CLOGE2("key(%d), size(%zu)", *iter, list->size());
            iter++;
        }
    } else {
        CLOGE2("m_getCallbackResults failed, size is ZERO, size(%zu)",
                 list->size());
    }

    m_requestCbListLock.unlock();

}

status_t ExynosCameraCallbackSequencer::flush()
{
    Mutex::Autolock lock(m_requestCbListLock);
    status_t ret = NO_ERROR;

    m_runningRequestKeys.clear();
    return ret;
}

status_t ExynosCameraCallbackSequencer::m_init()
{
    Mutex::Autolock lock(m_requestCbListLock);
    status_t ret = NO_ERROR;

    m_runningRequestKeys.clear();
    return ret;
}

status_t ExynosCameraCallbackSequencer::m_deinit()
{
    Mutex::Autolock lock(m_requestCbListLock);
    status_t ret = NO_ERROR;

    m_runningRequestKeys.clear();
    return ret;
}

status_t ExynosCameraCallbackSequencer::m_push(EXYNOS_LIST_OPER::MODE operMode,
                                                uint32_t key,
                                                CallbackListkeys *list,
                                                Mutex *lock)
{
    status_t ret = NO_ERROR;

    lock->lock();

    switch (operMode) {
    case EXYNOS_LIST_OPER::SINGLE_BACK:
        list->push_back(key);
        break;
    case EXYNOS_LIST_OPER::SINGLE_FRONT:
        list->push_front(key);
        break;
    case EXYNOS_LIST_OPER::SINGLE_ORDER:
    case EXYNOS_LIST_OPER::MULTI_GET:
    default:
        ret = INVALID_OPERATION;
        CLOGE2("m_push failed, mode(%d) size(%zu)", operMode, list->size());
        break;
    }

    lock->unlock();

    CLOGV2("m_push(%d), size(%zu)", key, list->size());

    return ret;
}

uint32_t ExynosCameraCallbackSequencer::m_pop(EXYNOS_LIST_OPER::MODE operMode, CallbackListkeys *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    CallbackListkeysIter iter;
    uint32_t obj = 0;

    lock->lock();

    switch (operMode) {
    case EXYNOS_LIST_OPER::SINGLE_BACK:
        if (list->size() > 0) {
            obj = list->back();
            list->pop_back();
        } else {
            CLOGE2("m_pop failed, size(%zu)", list->size());
            ret = INVALID_OPERATION;
        }
        break;
    case EXYNOS_LIST_OPER::SINGLE_FRONT:
        if (list->size() > 0) {
            obj = list->front();
            list->pop_front();
        } else {
            CLOGE2("m_pop failed, size(%zu)", list->size());
            ret = INVALID_OPERATION;
        }
        break;
    case EXYNOS_LIST_OPER::SINGLE_ORDER:
    case EXYNOS_LIST_OPER::MULTI_GET:
    default:
        ret = INVALID_OPERATION;
        obj = 0;
        CLOGE2("m_push failed, mode(%d) size(%zu)", operMode, list->size());
        break;
    }

    lock->unlock();

    CLOGI2("m_pop(%d), size(%zu)", obj, list->size());

    return obj;
}

uint32_t ExynosCameraCallbackSequencer::m_get(EXYNOS_LIST_OPER::MODE operMode, CallbackListkeys *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    CallbackListkeysIter iter;
    uint32_t obj = 0;

    lock->lock();

    switch (operMode) {
    case EXYNOS_LIST_OPER::SINGLE_BACK:
        if (list->size() > 0) {
            obj = list->back();
        } else {
            CLOGE2("m_get failed, size(%zu)", list->size());
            ret = INVALID_OPERATION;
        }
        break;
    case EXYNOS_LIST_OPER::SINGLE_FRONT:
        if (list->size() > 0) {
            obj = list->front();
        } else {
            CLOGE2("m_get failed, size(%zu)", list->size());
            ret = INVALID_OPERATION;
        }
        break;
    case EXYNOS_LIST_OPER::SINGLE_ORDER:
    case EXYNOS_LIST_OPER::MULTI_GET:
    default:
        ret = INVALID_OPERATION;
        obj = 0;
        CLOGE2("m_get failed, mode(%d) size(%zu)", operMode, list->size());
        break;
    }

    lock->unlock();

    CLOGV2("m_get(%d), size(%zu)", obj, list->size());

    return obj;
}

status_t ExynosCameraCallbackSequencer::m_delete(uint32_t key, CallbackListkeys *list, Mutex *lock)
{
    status_t ret = NO_ERROR;
    CallbackListkeysIter iter;

    lock->lock();

    if (list->size() > 0) {
        for (iter = list->begin(); iter != list->end();) {
            if (key == (uint32_t)*iter) {
                list->erase(iter++);
                CLOGV2("key(%d), size(%zu)", key, list->size());
            } else {
                iter++;
            }
        }
    } else {
        ret = INVALID_OPERATION;
        CLOGE2("m_getCallbackResults failed, size is ZERO, size(%zu)", list->size());
    }

    lock->unlock();

    CLOGV2("size(%zu)", list->size());

    return ret;
}

}; /* namespace android */
