1/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6*     * Redistributions of source code must retain the above copyright
7*       notice, this list of conditions and the following disclaimer.
8*     * Redistributions in binary form must reproduce the above
9*       copyright notice, this list of conditions and the following
10*       disclaimer in the documentation and/or other materials provided
11*       with the distribution.
12*     * Neither the name of The Linux Foundation nor the names of its
13*       contributors may be used to endorse or promote products derived
14*       from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29
30#define LOG_TAG "QCameraStateMachine"
31
32#include <utils/Errors.h>
33#include "QCamera2HWI.h"
34#include "QCameraStateMachine.h"
35
36namespace qcamera {
37
38/*===========================================================================
39 * FUNCTION   : smEvtProcRoutine
40 *
41 * DESCRIPTION: Statemachine process thread routine to handle events
42 *              in different state.
43 *
44 * PARAMETERS :
45 *   @data    : ptr to QCameraStateMachine object
46 *
47 * RETURN     : none
48 *==========================================================================*/
49void *QCameraStateMachine::smEvtProcRoutine(void *data)
50{
51    int running = 1, ret;
52    QCameraStateMachine *pme = (QCameraStateMachine *)data;
53
54    ALOGD("%s: E", __func__);
55    do {
56        do {
57            ret = cam_sem_wait(&pme->cmd_sem);
58            if (ret != 0 && errno != EINVAL) {
59                ALOGE("%s: cam_sem_wait error (%s)",
60                           __func__, strerror(errno));
61                return NULL;
62            }
63        } while (ret != 0);
64
65        // we got notified about new cmd avail in cmd queue
66        // first check API cmd queue
67        qcamera_sm_cmd_t *node = (qcamera_sm_cmd_t *)pme->api_queue.dequeue();
68        if (node == NULL) {
69            // no API cmd, then check evt cmd queue
70            node = (qcamera_sm_cmd_t *)pme->evt_queue.dequeue();
71        }
72        if (node != NULL) {
73            switch (node->cmd) {
74            case QCAMERA_SM_CMD_TYPE_API:
75                pme->stateMachine(node->evt, node->evt_payload);
76                // API is in a way sync call, so evt_payload is managed by HWI
77                // no need to free payload for API
78                break;
79            case QCAMERA_SM_CMD_TYPE_EVT:
80                pme->stateMachine(node->evt, node->evt_payload);
81
82                // EVT is async call, so payload need to be free after use
83                free(node->evt_payload);
84                node->evt_payload = NULL;
85                break;
86            case QCAMERA_SM_CMD_TYPE_EXIT:
87                running = 0;
88                break;
89            default:
90                break;
91            }
92            free(node);
93            node = NULL;
94        }
95    } while (running);
96    ALOGD("%s: X", __func__);
97    return NULL;
98}
99
100/*===========================================================================
101 * FUNCTION   : QCameraStateMachine
102 *
103 * DESCRIPTION: constructor of QCameraStateMachine. Will start process thread
104 *
105 * PARAMETERS :
106 *   @ctrl    : ptr to HWI object
107 *
108 * RETURN     : none
109 *==========================================================================*/
110QCameraStateMachine::QCameraStateMachine(QCamera2HardwareInterface *ctrl) :
111    api_queue(),
112    evt_queue()
113{
114    m_parent = ctrl;
115    m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
116    cmd_pid = 0;
117    cam_sem_init(&cmd_sem, 0);
118    pthread_create(&cmd_pid,
119                   NULL,
120                   smEvtProcRoutine,
121                   this);
122}
123
124/*===========================================================================
125 * FUNCTION   : ~QCameraStateMachine
126 *
127 * DESCRIPTION: desctructor of QCameraStateMachine. Will stop process thread.
128 *
129 * PARAMETERS : none
130 *
131 * RETURN     : none
132 *==========================================================================*/
133QCameraStateMachine::~QCameraStateMachine()
134{
135    if (cmd_pid != 0) {
136        qcamera_sm_cmd_t *node =
137            (qcamera_sm_cmd_t *)malloc(sizeof(qcamera_sm_cmd_t));
138        if (NULL != node) {
139            memset(node, 0, sizeof(qcamera_sm_cmd_t));
140            node->cmd = QCAMERA_SM_CMD_TYPE_EXIT;
141
142            api_queue.enqueue((void *)node);
143            cam_sem_post(&cmd_sem);
144
145            /* wait until cmd thread exits */
146            if (pthread_join(cmd_pid, NULL) != 0) {
147                ALOGD("%s: pthread dead already\n", __func__);
148            }
149        }
150        cmd_pid = 0;
151    }
152    cam_sem_destroy(&cmd_sem);
153}
154
155/*===========================================================================
156 * FUNCTION   : procAPI
157 *
158 * DESCRIPTION: process incoming API request from framework layer.
159 *
160 * PARAMETERS :
161 *   @evt          : event to be processed
162 *   @api_payload  : API payload. Can be NULL if not needed.
163 *
164 * RETURN     : int32_t type of status
165 *              NO_ERROR  -- success
166 *              none-zero failure code
167 *==========================================================================*/
168int32_t QCameraStateMachine::procAPI(qcamera_sm_evt_enum_t evt,
169                                     void *api_payload)
170{
171    qcamera_sm_cmd_t *node =
172        (qcamera_sm_cmd_t *)malloc(sizeof(qcamera_sm_cmd_t));
173    if (NULL == node) {
174        ALOGE("%s: No memory for qcamera_sm_cmd_t", __func__);
175        return NO_MEMORY;
176    }
177
178    memset(node, 0, sizeof(qcamera_sm_cmd_t));
179    node->cmd = QCAMERA_SM_CMD_TYPE_API;
180    node->evt = evt;
181    node->evt_payload = api_payload;
182    if (api_queue.enqueue((void *)node)) {
183        cam_sem_post(&cmd_sem);
184        return NO_ERROR;
185    } else {
186        free(node);
187        return UNKNOWN_ERROR;
188    }
189}
190
191/*===========================================================================
192 * FUNCTION   : procEvt
193 *
194 * DESCRIPTION: process incoming envent from mm-camera-interface and
195 *              mm-jpeg-interface.
196 *
197 * PARAMETERS :
198 *   @evt          : event to be processed
199 *   @evt_payload  : event payload. Can be NULL if not needed.
200 *
201 * RETURN     : int32_t type of status
202 *              NO_ERROR  -- success
203 *              none-zero failure code
204 *==========================================================================*/
205int32_t QCameraStateMachine::procEvt(qcamera_sm_evt_enum_t evt,
206                                     void *evt_payload)
207{
208    qcamera_sm_cmd_t *node =
209        (qcamera_sm_cmd_t *)malloc(sizeof(qcamera_sm_cmd_t));
210    if (NULL == node) {
211        ALOGE("%s: No memory for qcamera_sm_cmd_t", __func__);
212        return NO_MEMORY;
213    }
214
215    memset(node, 0, sizeof(qcamera_sm_cmd_t));
216    node->cmd = QCAMERA_SM_CMD_TYPE_EVT;
217    node->evt = evt;
218    node->evt_payload = evt_payload;
219    if (evt_queue.enqueue((void *)node)) {
220        cam_sem_post(&cmd_sem);
221        return NO_ERROR;
222    } else {
223        free(node);
224        return UNKNOWN_ERROR;
225    }
226}
227
228/*===========================================================================
229 * FUNCTION   : stateMachine
230 *
231 * DESCRIPTION: finite state machine entry function. Depends on state,
232 *              incoming event will be handled differently.
233 *
234 * PARAMETERS :
235 *   @evt      : event to be processed
236 *   @payload  : event payload. Can be NULL if not needed.
237 *
238 * RETURN     : int32_t type of status
239 *              NO_ERROR  -- success
240 *              none-zero failure code
241 *==========================================================================*/
242int32_t QCameraStateMachine::stateMachine(qcamera_sm_evt_enum_t evt, void *payload)
243{
244    int32_t rc = NO_ERROR;
245    switch (m_state) {
246    case QCAMERA_SM_STATE_PREVIEW_STOPPED:
247        rc = procEvtPreviewStoppedState(evt, payload);
248        break;
249    case QCAMERA_SM_STATE_PREVIEW_READY:
250        rc = procEvtPreviewReadyState(evt, payload);
251        break;
252    case QCAMERA_SM_STATE_PREVIEWING:
253        rc = procEvtPreviewingState(evt, payload);
254        break;
255    case QCAMERA_SM_STATE_PREPARE_SNAPSHOT:
256        rc = procEvtPrepareSnapshotState(evt, payload);
257        break;
258    case QCAMERA_SM_STATE_PIC_TAKING:
259        rc = procEvtPicTakingState(evt, payload);
260        break;
261    case QCAMERA_SM_STATE_RECORDING:
262        rc = procEvtRecordingState(evt, payload);
263        break;
264    case QCAMERA_SM_STATE_VIDEO_PIC_TAKING:
265        rc = procEvtVideoPicTakingState(evt, payload);
266        break;
267    case QCAMERA_SM_STATE_PREVIEW_PIC_TAKING:
268        rc = procEvtPreviewPicTakingState(evt, payload);
269        break;
270    default:
271        break;
272    }
273
274    return rc;
275}
276
277/*===========================================================================
278 * FUNCTION   : procEvtPreviewStoppedState
279 *
280 * DESCRIPTION: finite state machine function to handle event in state of
281 *              QCAMERA_SM_STATE_PREVIEW_STOPPED.
282 *
283 * PARAMETERS :
284 *   @evt      : event to be processed
285 *   @payload  : event payload. Can be NULL if not needed.
286 *
287 * RETURN     : int32_t type of status
288 *              NO_ERROR  -- success
289 *              none-zero failure code
290 *==========================================================================*/
291int32_t QCameraStateMachine::procEvtPreviewStoppedState(qcamera_sm_evt_enum_t evt,
292                                                        void *payload)
293{
294    int32_t rc = NO_ERROR;
295    qcamera_api_result_t result;
296    memset(&result, 0, sizeof(qcamera_api_result_t));
297
298    switch (evt) {
299    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
300        {
301            rc = m_parent->setPreviewWindow((struct preview_stream_ops *)payload);
302            result.status = rc;
303            result.request_api = evt;
304            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
305            m_parent->signalAPIResult(&result);
306        }
307        break;
308    case QCAMERA_SM_EVT_SET_CALLBACKS:
309        {
310            qcamera_sm_evt_setcb_payload_t *setcbs =
311                (qcamera_sm_evt_setcb_payload_t *)payload;
312            rc = m_parent->setCallBacks(setcbs->notify_cb,
313                                        setcbs->data_cb,
314                                        setcbs->data_cb_timestamp,
315                                        setcbs->get_memory,
316                                        setcbs->user);
317            result.status = rc;
318            result.request_api = evt;
319            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
320            m_parent->signalAPIResult(&result);
321        }
322        break;
323    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
324        {
325            rc = m_parent->enableMsgType(int32_t(payload));
326            result.status = rc;
327            result.request_api = evt;
328            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
329            m_parent->signalAPIResult(&result);
330        }
331        break;
332    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
333        {
334            rc = m_parent->disableMsgType(int32_t(payload));
335            result.status = rc;
336            result.request_api = evt;
337            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
338            m_parent->signalAPIResult(&result);
339        }
340        break;
341    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
342        {
343            int enabled = m_parent->msgTypeEnabled(int32_t(payload));
344            result.status = rc;
345            result.request_api = evt;
346            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
347            result.enabled = enabled;
348            m_parent->signalAPIResult(&result);
349        }
350        break;
351    case QCAMERA_SM_EVT_SET_PARAMS:
352        {
353            bool needRestart = false;
354            rc = m_parent->updateParameters((char*)payload, needRestart);
355            if (rc == NO_ERROR) {
356                rc = m_parent->commitParameterChanges();
357            }
358            result.status = rc;
359            result.request_api = evt;
360            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
361            m_parent->signalAPIResult(&result);
362        }
363        break;
364    case QCAMERA_SM_EVT_GET_PARAMS:
365        {
366            result.params = m_parent->getParameters();
367            rc = NO_ERROR;
368            result.status = rc;
369            result.request_api = evt;
370            result.result_type = QCAMERA_API_RESULT_TYPE_PARAMS;
371            m_parent->signalAPIResult(&result);
372        }
373        break;
374    case QCAMERA_SM_EVT_PUT_PARAMS:
375        {
376            rc = m_parent->putParameters((char*)payload);
377            result.status = rc;
378            result.request_api = evt;
379            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
380            m_parent->signalAPIResult(&result);
381        }
382        break;
383    case QCAMERA_SM_EVT_START_PREVIEW:
384        {
385            if (m_parent->mPreviewWindow == NULL) {
386                rc = m_parent->preparePreview();
387                if(rc == NO_ERROR) {
388                    // preview window is not set yet, move to previewReady state
389                    m_state = QCAMERA_SM_STATE_PREVIEW_READY;
390                } else {
391                    ALOGE("%s: preparePreview failed",__func__);
392                }
393            } else {
394                rc = m_parent->preparePreview();
395                if (rc == NO_ERROR) {
396                    rc = m_parent->startPreview();
397                    if (rc != NO_ERROR) {
398                        m_parent->unpreparePreview();
399                    } else {
400                        // start preview success, move to previewing state
401                        m_state = QCAMERA_SM_STATE_PREVIEWING;
402                    }
403                }
404            }
405            result.status = rc;
406            result.request_api = evt;
407            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
408            m_parent->signalAPIResult(&result);
409        }
410        break;
411    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
412        {
413            rc = m_parent->preparePreview();
414            if (rc == NO_ERROR) {
415                rc = m_parent->startPreview();
416                if (rc != NO_ERROR) {
417                    m_parent->unpreparePreview();
418                } else {
419                    m_state = QCAMERA_SM_STATE_PREVIEWING;
420                }
421            }
422            result.status = rc;
423            result.request_api = evt;
424            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
425            m_parent->signalAPIResult(&result);
426        }
427    break;
428    case QCAMERA_SM_EVT_STOP_PREVIEW:
429        {
430            // no op needed here
431            ALOGD("%s: already in preview stopped state, do nothing", __func__);
432            result.status = NO_ERROR;
433            result.request_api = evt;
434            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
435            m_parent->signalAPIResult(&result);
436        }
437        break;
438    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
439    case QCAMERA_SM_EVT_RECORDING_ENABLED:
440        {
441            result.status = NO_ERROR;
442            result.request_api = evt;
443            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
444            result.enabled = 0;
445            m_parent->signalAPIResult(&result);
446        }
447        break;
448    case QCAMERA_SM_EVT_RELEASE:
449        {
450            rc = m_parent->release();
451            result.status = rc;
452            result.request_api = evt;
453            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
454            m_parent->signalAPIResult(&result);
455        }
456        break;
457    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
458        {
459            rc = m_parent->storeMetaDataInBuffers(int(payload));
460            result.status = rc;
461            result.request_api = evt;
462            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
463            m_parent->signalAPIResult(&result);
464        }
465        break;
466    case QCAMERA_SM_EVT_DUMP:
467        {
468            rc = m_parent->dump((int)payload);
469            result.status = rc;
470            result.request_api = evt;
471            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
472            m_parent->signalAPIResult(&result);
473        }
474        break;
475    case QCAMERA_SM_EVT_SEND_COMMAND:
476        {
477            qcamera_sm_evt_command_payload_t *cmd_payload =
478                (qcamera_sm_evt_command_payload_t *)payload;
479            rc = m_parent->sendCommand(cmd_payload->cmd,
480                                       cmd_payload->arg1,
481                                       cmd_payload->arg2);
482            result.status = rc;
483            result.request_api = evt;
484            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
485            m_parent->signalAPIResult(&result);
486        }
487        break;
488    case QCAMERA_SM_EVT_START_RECORDING:
489    case QCAMERA_SM_EVT_STOP_RECORDING:
490    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
491    case QCAMERA_SM_EVT_PREPARE_SNAPSHOT:
492    case QCAMERA_SM_EVT_TAKE_PICTURE:
493    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
494        {
495            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
496            rc = INVALID_OPERATION;
497            result.status = rc;
498            result.request_api = evt;
499            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
500            m_parent->signalAPIResult(&result);
501        }
502        break;
503    case QCAMERA_SM_EVT_CANCEL_PICTURE:
504        {
505            // no op needed here
506            ALOGD("%s: No ops for evt(%d) in state(%d)", __func__, evt, m_state);
507            result.status = NO_ERROR;
508            result.request_api = evt;
509            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
510            m_parent->signalAPIResult(&result);
511        }
512        break;
513    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
514        {
515            rc = m_parent->cancelAutoFocus();
516            result.status = rc;
517            result.request_api = evt;
518            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
519            m_parent->signalAPIResult(&result);
520        }
521        break;
522    case QCAMERA_SM_EVT_REG_FACE_IMAGE:
523        {
524            int32_t faceID = 0;
525            qcamera_sm_evt_reg_face_payload_t *reg_payload =
526                (qcamera_sm_evt_reg_face_payload_t *)payload;
527            rc = m_parent->registerFaceImage(reg_payload->img_ptr,
528                                             reg_payload->config,
529                                             faceID);
530            result.status = rc;
531            result.request_api = evt;
532            result.result_type = QCAMERA_API_RESULT_TYPE_HANDLE;
533            result.handle = faceID;
534            m_parent->signalAPIResult(&result);
535        }
536        break;
537    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
538        {
539            rc = m_parent->updateThermalLevel(
540                    *(qcamera_thermal_level_enum_t *)&payload);
541        }
542        break;
543    case QCAMERA_SM_EVT_EVT_NOTIFY:
544        {
545            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
546            switch (cam_evt->server_event_type) {
547            case CAM_EVENT_TYPE_DAEMON_DIED:
548                {
549                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
550                                            CAMERA_ERROR_SERVER_DIED,
551                                            0);
552                }
553                break;
554            default:
555                ALOGE("%s: Invalid internal event %d in state(%d)",
556                            __func__, cam_evt->server_event_type, m_state);
557                break;
558            }
559        }
560        break;
561    case QCAMERA_SM_EVT_EVT_INTERNAL:
562    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
563    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
564    default:
565        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
566        break;
567    }
568
569    return rc;
570}
571
572/*===========================================================================
573 * FUNCTION   : procEvtPreviewReadyState
574 *
575 * DESCRIPTION: finite state machine function to handle event in state of
576 *              QCAMERA_SM_STATE_PREVIEW_READY.
577 *
578 * PARAMETERS :
579 *   @evt      : event to be processed
580 *   @payload  : event payload. Can be NULL if not needed.
581 *
582 * RETURN     : int32_t type of status
583 *              NO_ERROR  -- success
584 *              none-zero failure code
585 *==========================================================================*/
586int32_t QCameraStateMachine::procEvtPreviewReadyState(qcamera_sm_evt_enum_t evt,
587                                                      void *payload)
588{
589    int32_t rc = NO_ERROR;
590    qcamera_api_result_t result;
591    memset(&result, 0, sizeof(qcamera_api_result_t));
592
593    switch (evt) {
594    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
595        {
596            m_parent->setPreviewWindow((struct preview_stream_ops *)payload);
597            if (m_parent->mPreviewWindow != NULL) {
598                rc = m_parent->startPreview();
599                if (rc != NO_ERROR) {
600                    m_parent->unpreparePreview();
601                    m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
602                } else {
603                    m_state = QCAMERA_SM_STATE_PREVIEWING;
604                }
605            }
606
607            result.status = rc;
608            result.request_api = evt;
609            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
610            m_parent->signalAPIResult(&result);
611        }
612        break;
613    case QCAMERA_SM_EVT_SET_CALLBACKS:
614        {
615            qcamera_sm_evt_setcb_payload_t *setcbs =
616                (qcamera_sm_evt_setcb_payload_t *)payload;
617            rc = m_parent->setCallBacks(setcbs->notify_cb,
618                                        setcbs->data_cb,
619                                        setcbs->data_cb_timestamp,
620                                        setcbs->get_memory,
621                                        setcbs->user);
622            result.status = rc;
623            result.request_api = evt;
624            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
625            m_parent->signalAPIResult(&result);
626        }
627        break;
628    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
629        {
630            rc = m_parent->enableMsgType(int32_t(payload));
631            result.status = rc;
632            result.request_api = evt;
633            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
634            m_parent->signalAPIResult(&result);
635        }
636        break;
637    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
638        {
639            rc = m_parent->disableMsgType(int32_t(payload));
640            result.status = rc;
641            result.request_api = evt;
642            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
643            m_parent->signalAPIResult(&result);
644        }
645        break;
646    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
647        {
648            int enabled = m_parent->msgTypeEnabled(int32_t(payload));
649            result.status = rc;
650            result.request_api = evt;
651            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
652            result.enabled = enabled;
653            m_parent->signalAPIResult(&result);
654        }
655        break;
656    case QCAMERA_SM_EVT_SET_PARAMS:
657        {
658            bool needRestart = false;
659            rc = m_parent->updateParameters((char*)payload, needRestart);
660            if (rc == NO_ERROR) {
661                if (needRestart) {
662                    // need restart preview for parameters to take effect
663                    m_parent->unpreparePreview();
664                    // commit parameter changes to server
665                    m_parent->commitParameterChanges();
666                    // prepare preview again
667                    rc = m_parent->preparePreview();
668                    if (rc != NO_ERROR) {
669                        m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
670                    }
671                } else {
672                    rc = m_parent->commitParameterChanges();
673                }
674            }
675
676            result.status = rc;
677            result.request_api = evt;
678            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
679            m_parent->signalAPIResult(&result);
680        }
681        break;
682    case QCAMERA_SM_EVT_GET_PARAMS:
683        {
684            result.params = m_parent->getParameters();
685            rc = NO_ERROR;
686            result.status = rc;
687            result.request_api = evt;
688            result.result_type = QCAMERA_API_RESULT_TYPE_PARAMS;
689            m_parent->signalAPIResult(&result);
690        }
691        break;
692    case QCAMERA_SM_EVT_PUT_PARAMS:
693        {
694            rc = m_parent->putParameters((char*)payload);
695            result.status = rc;
696            result.request_api = evt;
697            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
698            m_parent->signalAPIResult(&result);
699        }
700        break;
701    case QCAMERA_SM_EVT_START_PREVIEW:
702        {
703            // no ops here
704            rc = NO_ERROR;
705            result.status = rc;
706            result.request_api = evt;
707            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
708            m_parent->signalAPIResult(&result);
709        }
710        break;
711    case QCAMERA_SM_EVT_STOP_PREVIEW:
712        {
713            m_parent->unpreparePreview();
714            rc = 0;
715            m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
716            result.status = rc;
717            result.request_api = evt;
718            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
719            m_parent->signalAPIResult(&result);
720        }
721        break;
722    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
723        {
724            rc = NO_ERROR;
725            result.status = rc;
726            result.request_api = evt;
727            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
728            result.enabled = 1;
729            m_parent->signalAPIResult(&result);
730        }
731        break;
732    case QCAMERA_SM_EVT_RECORDING_ENABLED:
733        {
734            rc = 0;
735            result.status = rc;
736            result.request_api = evt;
737            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
738            result.enabled = 0;
739            m_parent->signalAPIResult(&result);
740        }
741        break;
742    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
743        {
744            rc = m_parent->storeMetaDataInBuffers(int(payload));
745            result.status = rc;
746            result.request_api = evt;
747            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
748            m_parent->signalAPIResult(&result);
749        }
750        break;
751    case QCAMERA_SM_EVT_DUMP:
752        {
753            rc = m_parent->dump((int)payload);
754            result.status = rc;
755            result.request_api = evt;
756            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
757            m_parent->signalAPIResult(&result);
758        }
759        break;
760    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
761        {
762            rc = m_parent->autoFocus();
763            result.status = rc;
764            result.request_api = evt;
765            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
766            m_parent->signalAPIResult(&result);
767        }
768        break;
769    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
770        {
771            rc = m_parent->cancelAutoFocus();
772            result.status = rc;
773            result.request_api = evt;
774            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
775            m_parent->signalAPIResult(&result);
776        }
777        break;
778    case QCAMERA_SM_EVT_SEND_COMMAND:
779        {
780            qcamera_sm_evt_command_payload_t *cmd_payload =
781                (qcamera_sm_evt_command_payload_t *)payload;
782            rc = m_parent->sendCommand(cmd_payload->cmd,
783                                       cmd_payload->arg1,
784                                       cmd_payload->arg2);
785            result.status = rc;
786            result.request_api = evt;
787            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
788            m_parent->signalAPIResult(&result);
789        }
790        break;
791    case QCAMERA_SM_EVT_REG_FACE_IMAGE:
792        {
793            int32_t faceID = 0;
794            qcamera_sm_evt_reg_face_payload_t *reg_payload =
795                (qcamera_sm_evt_reg_face_payload_t *)payload;
796            rc = m_parent->registerFaceImage(reg_payload->img_ptr,
797                                             reg_payload->config,
798                                             faceID);
799            result.status = rc;
800            result.request_api = evt;
801            result.result_type = QCAMERA_API_RESULT_TYPE_HANDLE;
802            result.handle = faceID;
803            m_parent->signalAPIResult(&result);
804        }
805        break;
806    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
807    case QCAMERA_SM_EVT_START_RECORDING:
808    case QCAMERA_SM_EVT_STOP_RECORDING:
809    case QCAMERA_SM_EVT_PREPARE_SNAPSHOT:
810    case QCAMERA_SM_EVT_TAKE_PICTURE:
811    case QCAMERA_SM_EVT_CANCEL_PICTURE:
812    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
813    case QCAMERA_SM_EVT_RELEASE:
814        {
815            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
816            rc = INVALID_OPERATION;
817            result.status = rc;
818            result.request_api = evt;
819            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
820            m_parent->signalAPIResult(&result);
821        }
822        break;
823    case QCAMERA_SM_EVT_EVT_NOTIFY:
824        {
825            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
826            switch (cam_evt->server_event_type) {
827            case CAM_EVENT_TYPE_DAEMON_DIED:
828                {
829                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
830                                            CAMERA_ERROR_SERVER_DIED,
831                                            0);
832                }
833                break;
834            default:
835                ALOGE("%s: Invalid internal event %d in state(%d)",
836                            __func__, cam_evt->server_event_type, m_state);
837                break;
838            }
839        }
840        break;
841    case QCAMERA_SM_EVT_EVT_INTERNAL:
842    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
843    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
844    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
845    default:
846        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
847        break;
848    }
849
850    return rc;
851}
852
853/*===========================================================================
854 * FUNCTION   : procEvtPreviewingState
855 *
856 * DESCRIPTION: finite state machine function to handle event in state of
857 *              QCAMERA_SM_STATE_PREVIEWING.
858 *
859 * PARAMETERS :
860 *   @evt      : event to be processed
861 *   @payload  : event payload. Can be NULL if not needed.
862 *
863 * RETURN     : int32_t type of status
864 *              NO_ERROR  -- success
865 *              none-zero failure code
866 *==========================================================================*/
867int32_t QCameraStateMachine::procEvtPreviewingState(qcamera_sm_evt_enum_t evt,
868                                                    void *payload)
869{
870    int32_t rc = NO_ERROR;
871    qcamera_api_result_t result;
872    memset(&result, 0, sizeof(qcamera_api_result_t));
873
874    switch (evt) {
875    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
876        {
877            // Error setting preview window during previewing
878            ALOGE("Cannot set preview window when preview is running");
879            rc = INVALID_OPERATION;
880            result.status = rc;
881            result.request_api = evt;
882            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
883            m_parent->signalAPIResult(&result);
884        }
885        break;
886    case QCAMERA_SM_EVT_SET_CALLBACKS:
887        {
888            qcamera_sm_evt_setcb_payload_t *setcbs =
889                (qcamera_sm_evt_setcb_payload_t *)payload;
890            rc = m_parent->setCallBacks(setcbs->notify_cb,
891                                        setcbs->data_cb,
892                                        setcbs->data_cb_timestamp,
893                                        setcbs->get_memory,
894                                        setcbs->user);
895            result.status = rc;
896            result.request_api = evt;
897            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
898            m_parent->signalAPIResult(&result);
899        }
900        break;
901    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
902        {
903            rc = m_parent->enableMsgType(int32_t(payload));
904            result.status = rc;
905            result.request_api = evt;
906            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
907            m_parent->signalAPIResult(&result);
908        }
909        break;
910    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
911        {
912            rc = m_parent->disableMsgType(int32_t(payload));
913            result.status = rc;
914            result.request_api = evt;
915            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
916            m_parent->signalAPIResult(&result);
917        }
918        break;
919    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
920        {
921            int enabled = m_parent->msgTypeEnabled(int32_t(payload));
922            result.status = rc;
923            result.request_api = evt;
924            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
925            result.enabled = enabled;
926            m_parent->signalAPIResult(&result);
927        }
928        break;
929    case QCAMERA_SM_EVT_SET_PARAMS:
930        {
931            bool needRestart = false;
932            rc = m_parent->updateParameters((char*)payload, needRestart);
933            if (rc == NO_ERROR) {
934                if (needRestart) {
935                    // need restart preview for parameters to take effect
936                    // stop preview
937                    m_parent->stopPreview();
938                    // commit parameter changes to server
939                    m_parent->commitParameterChanges();
940                    // start preview again
941                    rc = m_parent->preparePreview();
942                    if (rc == NO_ERROR) {
943                        rc = m_parent->startPreview();
944                        if (rc != NO_ERROR) {
945                            m_parent->unpreparePreview();
946                        }
947                    }
948                    if (rc != NO_ERROR) {
949                        m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
950                    }
951                } else {
952                    rc = m_parent->commitParameterChanges();
953                }
954            }
955            result.status = rc;
956            result.request_api = evt;
957            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
958            m_parent->signalAPIResult(&result);
959        }
960        break;
961    case QCAMERA_SM_EVT_GET_PARAMS:
962        {
963            result.params = m_parent->getParameters();
964            rc = NO_ERROR;
965            result.status = rc;
966            result.request_api = evt;
967            result.result_type = QCAMERA_API_RESULT_TYPE_PARAMS;
968            m_parent->signalAPIResult(&result);
969        }
970        break;
971    case QCAMERA_SM_EVT_PUT_PARAMS:
972        {
973            rc = m_parent->putParameters((char*)payload);
974            result.status = rc;
975            result.request_api = evt;
976            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
977            m_parent->signalAPIResult(&result);
978        }
979        break;
980    case QCAMERA_SM_EVT_START_PREVIEW:
981    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
982        {
983            // no ops here
984            ALOGD("%s: Already in previewing, no ops here to start preview", __func__);
985            rc = NO_ERROR;
986            result.status = rc;
987            result.request_api = evt;
988            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
989            m_parent->signalAPIResult(&result);
990        }
991        break;
992    case QCAMERA_SM_EVT_STOP_PREVIEW:
993        {
994            rc = m_parent->stopPreview();
995            m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
996            result.status = rc;
997            result.request_api = evt;
998            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
999            m_parent->signalAPIResult(&result);
1000        }
1001        break;
1002    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
1003        {
1004            rc = NO_ERROR;
1005            result.status = rc;
1006            result.request_api = evt;
1007            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1008            result.enabled = 1;
1009            m_parent->signalAPIResult(&result);
1010        }
1011        break;
1012    case QCAMERA_SM_EVT_RECORDING_ENABLED:
1013        {
1014            rc = NO_ERROR;
1015            result.status = rc;
1016            result.request_api = evt;
1017            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1018            result.enabled = 0;
1019            m_parent->signalAPIResult(&result);
1020        }
1021        break;
1022    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
1023        {
1024            rc = m_parent->storeMetaDataInBuffers(int(payload));
1025            result.status = rc;
1026            result.request_api = evt;
1027            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1028            m_parent->signalAPIResult(&result);
1029        }
1030        break;
1031    case QCAMERA_SM_EVT_DUMP:
1032        {
1033            rc = m_parent->dump((int)payload);
1034            result.status = rc;
1035            result.request_api = evt;
1036            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1037            m_parent->signalAPIResult(&result);
1038        }
1039        break;
1040    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
1041        {
1042            rc = m_parent->autoFocus();
1043            result.status = rc;
1044            result.request_api = evt;
1045            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1046            m_parent->signalAPIResult(&result);
1047        }
1048        break;
1049    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
1050        {
1051            rc = m_parent->cancelAutoFocus();
1052            result.status = rc;
1053            result.request_api = evt;
1054            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1055            m_parent->signalAPIResult(&result);
1056        }
1057        break;
1058    case QCAMERA_SM_EVT_START_RECORDING:
1059        {
1060            rc = m_parent->startRecording();
1061            if (rc == NO_ERROR) {
1062                // move state to recording state
1063                m_state = QCAMERA_SM_STATE_RECORDING;
1064            }
1065            result.status = rc;
1066            result.request_api = evt;
1067            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1068            m_parent->signalAPIResult(&result);
1069        }
1070        break;
1071    case QCAMERA_SM_EVT_PREPARE_SNAPSHOT:
1072        {
1073            rc = m_parent->prepareHardwareForSnapshot(FALSE);
1074            if (rc == NO_ERROR) {
1075                // Do not signal API result in this case.
1076                // Need to wait for snapshot done in metadta.
1077                m_state = QCAMERA_SM_STATE_PREPARE_SNAPSHOT;
1078            } else {
1079                // Do not change state in this case.
1080                ALOGE("%s: prepareHardwareForSnapshot failed %d",
1081                    __func__, rc);
1082
1083                result.status = rc;
1084                result.request_api = evt;
1085                result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1086                m_parent->signalAPIResult(&result);
1087            }
1088        }
1089        break;
1090    case QCAMERA_SM_EVT_TAKE_PICTURE:
1091       {
1092           if ( m_parent->mParameters.getRecordingHintValue() == false) {
1093           rc = m_parent->takePicture();
1094           if (rc == NO_ERROR) {
1095               // move state to picture taking state
1096               if (m_parent->isZSLMode()) {
1097                   m_state = QCAMERA_SM_STATE_PREVIEW_PIC_TAKING;
1098               } else {
1099                   m_state = QCAMERA_SM_STATE_PIC_TAKING;
1100               }
1101            } else {
1102                // move state to preview stopped state
1103                m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
1104            }
1105            result.status = rc;
1106            result.request_api = evt;
1107            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1108            m_parent->signalAPIResult(&result);
1109           } else {
1110               rc = m_parent->takeLiveSnapshot();
1111               if (rc == NO_ERROR ) {
1112                   m_state = QCAMERA_SM_STATE_PREVIEW_PIC_TAKING;
1113                   result.status = rc;
1114                   result.request_api = evt;
1115                   result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1116                   m_parent->signalAPIResult(&result);
1117               }
1118           }
1119        }
1120        break;
1121    case QCAMERA_SM_EVT_SEND_COMMAND:
1122        {
1123            qcamera_sm_evt_command_payload_t *cmd_payload =
1124                (qcamera_sm_evt_command_payload_t *)payload;
1125            rc = m_parent->sendCommand(cmd_payload->cmd,
1126                                       cmd_payload->arg1,
1127                                       cmd_payload->arg2);
1128            result.status = rc;
1129            result.request_api = evt;
1130            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1131            m_parent->signalAPIResult(&result);
1132        }
1133        break;
1134    case QCAMERA_SM_EVT_REG_FACE_IMAGE:
1135        {
1136            int32_t faceID = 0;
1137            qcamera_sm_evt_reg_face_payload_t *reg_payload =
1138                (qcamera_sm_evt_reg_face_payload_t *)payload;
1139            rc = m_parent->registerFaceImage(reg_payload->img_ptr,
1140                                             reg_payload->config,
1141                                             faceID);
1142            result.status = rc;
1143            result.request_api = evt;
1144            result.result_type = QCAMERA_API_RESULT_TYPE_HANDLE;
1145            result.handle = faceID;
1146            m_parent->signalAPIResult(&result);
1147        }
1148        break;
1149    case QCAMERA_SM_EVT_CANCEL_PICTURE:
1150    case QCAMERA_SM_EVT_STOP_RECORDING:
1151    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
1152    case QCAMERA_SM_EVT_RELEASE:
1153        {
1154            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1155            rc = INVALID_OPERATION;
1156            result.status = rc;
1157            result.request_api = evt;
1158            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1159            m_parent->signalAPIResult(&result);
1160        }
1161        break;
1162    case QCAMERA_SM_EVT_EVT_INTERNAL:
1163        {
1164            qcamera_sm_internal_evt_payload_t *internal_evt =
1165                (qcamera_sm_internal_evt_payload_t *)payload;
1166            switch (internal_evt->evt_type) {
1167            case QCAMERA_INTERNAL_EVT_FOCUS_UPDATE:
1168                rc = m_parent->processAutoFocusEvent(internal_evt->focus_data);
1169                break;
1170            default:
1171                ALOGE("%s: Invalid internal event %d in state(%d)",
1172                            __func__, internal_evt->evt_type, m_state);
1173                break;
1174            }
1175        }
1176        break;
1177    case QCAMERA_SM_EVT_EVT_NOTIFY:
1178        {
1179            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
1180            switch (cam_evt->server_event_type) {
1181            case CAM_EVENT_TYPE_DAEMON_DIED:
1182                {
1183                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
1184                                            CAMERA_ERROR_SERVER_DIED,
1185                                            0);
1186                }
1187                break;
1188            default:
1189                ALOGD("%s: no handling for server evt (%d) at this state",
1190                      __func__, cam_evt->server_event_type);
1191                break;
1192            }
1193        }
1194        break;
1195    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
1196        {
1197            rc = m_parent->updateThermalLevel(
1198                    *(qcamera_thermal_level_enum_t *)&payload);
1199        }
1200        break;
1201    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
1202    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
1203    default:
1204        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1205        break;
1206    }
1207
1208    return rc;
1209}
1210
1211/*===========================================================================
1212 * FUNCTION   : procEvtPrepareSnapshotState
1213 *
1214 * DESCRIPTION: finite state machine function to handle event in state of
1215 *              QCAMERA_SM_STATE_PREPARE_SNAPSHOT.
1216 *
1217 * PARAMETERS :
1218 *   @evt      : event to be processed
1219 *   @payload  : event payload. Can be NULL if not needed.
1220 *
1221 * RETURN     : int32_t type of status
1222 *              NO_ERROR  -- success
1223 *              none-zero failure code
1224 *==========================================================================*/
1225int32_t QCameraStateMachine::procEvtPrepareSnapshotState(qcamera_sm_evt_enum_t evt,
1226                                                    void *payload)
1227{
1228    int32_t rc = NO_ERROR;
1229    qcamera_api_result_t result;
1230    memset(&result, 0, sizeof(qcamera_api_result_t));
1231
1232    switch (evt) {
1233    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
1234    case QCAMERA_SM_EVT_SET_CALLBACKS:
1235    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
1236    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
1237    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
1238    case QCAMERA_SM_EVT_SET_PARAMS:
1239    case QCAMERA_SM_EVT_GET_PARAMS:
1240    case QCAMERA_SM_EVT_PUT_PARAMS:
1241    case QCAMERA_SM_EVT_START_PREVIEW:
1242    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
1243    case QCAMERA_SM_EVT_STOP_PREVIEW:
1244    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
1245    case QCAMERA_SM_EVT_RECORDING_ENABLED:
1246    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
1247    case QCAMERA_SM_EVT_DUMP:
1248    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
1249    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
1250    case QCAMERA_SM_EVT_START_RECORDING:
1251    case QCAMERA_SM_EVT_TAKE_PICTURE:
1252    case QCAMERA_SM_EVT_SEND_COMMAND:
1253    case QCAMERA_SM_EVT_CANCEL_PICTURE:
1254    case QCAMERA_SM_EVT_STOP_RECORDING:
1255    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
1256    case QCAMERA_SM_EVT_RELEASE:
1257        {
1258            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1259            rc = INVALID_OPERATION;
1260            result.status = rc;
1261            result.request_api = evt;
1262            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1263            m_parent->signalAPIResult(&result);
1264        }
1265        break;
1266    case QCAMERA_SM_EVT_EVT_INTERNAL:
1267        {
1268            qcamera_sm_internal_evt_payload_t *internal_evt =
1269                (qcamera_sm_internal_evt_payload_t *)payload;
1270            switch (internal_evt->evt_type) {
1271            case QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE:
1272                ALOGI("%s: Received QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE event",
1273                    __func__);
1274                m_parent->processPrepSnapshotDoneEvent(internal_evt->prep_snapshot_state);
1275                m_state = QCAMERA_SM_STATE_PREVIEWING;
1276
1277                result.status = NO_ERROR;
1278                result.request_api = QCAMERA_SM_EVT_PREPARE_SNAPSHOT;
1279                result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1280                m_parent->signalAPIResult(&result);
1281                break;
1282            default:
1283                ALOGE("%s: Invalid internal event %d in state(%d)",
1284                            __func__, internal_evt->evt_type, m_state);
1285                break;
1286            }
1287        }
1288        break;
1289    case QCAMERA_SM_EVT_EVT_NOTIFY:
1290        {
1291            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
1292            switch (cam_evt->server_event_type) {
1293            case CAM_EVENT_TYPE_DAEMON_DIED:
1294                {
1295                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
1296                                            CAMERA_ERROR_SERVER_DIED,
1297                                            0);
1298                }
1299                break;
1300            default:
1301                ALOGE("%s: Invalid internal event %d in state(%d)",
1302                            __func__, cam_evt->server_event_type, m_state);
1303                break;
1304            }
1305        }
1306        break;
1307    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
1308    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
1309    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
1310    default:
1311        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1312        break;
1313    }
1314
1315    return rc;
1316}
1317
1318/*===========================================================================
1319 * FUNCTION   : procEvtPicTakingState
1320 *
1321 * DESCRIPTION: finite state machine function to handle event in state of
1322 *              QCAMERA_SM_STATE_PIC_TAKING.
1323 *
1324 * PARAMETERS :
1325 *   @evt      : event to be processed
1326 *   @payload  : event payload. Can be NULL if not needed.
1327 *
1328 * RETURN     : int32_t type of status
1329 *              NO_ERROR  -- success
1330 *              none-zero failure code
1331 *==========================================================================*/
1332int32_t QCameraStateMachine::procEvtPicTakingState(qcamera_sm_evt_enum_t evt,
1333                                                   void *payload)
1334{
1335    int32_t rc = NO_ERROR;
1336    qcamera_api_result_t result;
1337    memset(&result, 0, sizeof(qcamera_api_result_t));
1338
1339    switch (evt) {
1340    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
1341        {
1342            // Error setting preview window during previewing
1343            ALOGE("Cannot set preview window when preview is running");
1344            rc = INVALID_OPERATION;
1345            result.status = rc;
1346            result.request_api = evt;
1347            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1348            m_parent->signalAPIResult(&result);
1349        }
1350        break;
1351    case QCAMERA_SM_EVT_SET_CALLBACKS:
1352        {
1353            qcamera_sm_evt_setcb_payload_t *setcbs =
1354                (qcamera_sm_evt_setcb_payload_t *)payload;
1355            rc = m_parent->setCallBacks(setcbs->notify_cb,
1356                                        setcbs->data_cb,
1357                                        setcbs->data_cb_timestamp,
1358                                        setcbs->get_memory,
1359                                        setcbs->user);
1360            result.status = rc;
1361            result.request_api = evt;
1362            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1363            m_parent->signalAPIResult(&result);
1364        }
1365        break;
1366    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
1367        {
1368            rc = m_parent->enableMsgType(int32_t(payload));
1369            result.status = rc;
1370            result.request_api = evt;
1371            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1372            m_parent->signalAPIResult(&result);
1373        }
1374        break;
1375    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
1376        {
1377            rc = m_parent->disableMsgType(int32_t(payload));
1378            result.status = rc;
1379            result.request_api = evt;
1380            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1381            m_parent->signalAPIResult(&result);
1382        }
1383        break;
1384    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
1385        {
1386            int enabled = m_parent->msgTypeEnabled(int32_t(payload));
1387            result.status = rc;
1388            result.request_api = evt;
1389            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1390            result.enabled = enabled;
1391            m_parent->signalAPIResult(&result);
1392        }
1393        break;
1394    case QCAMERA_SM_EVT_SET_PARAMS:
1395        {
1396            bool needRestart = false;
1397            rc = m_parent->updateParameters((char*)payload, needRestart);
1398            if (rc == NO_ERROR) {
1399                rc = m_parent->commitParameterChanges();
1400            }
1401            result.status = rc;
1402            result.request_api = evt;
1403            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1404            m_parent->signalAPIResult(&result);
1405        }
1406        break;
1407    case QCAMERA_SM_EVT_GET_PARAMS:
1408        {
1409            result.params = m_parent->getParameters();
1410            rc = NO_ERROR;
1411            result.status = rc;
1412            result.request_api = evt;
1413            result.result_type = QCAMERA_API_RESULT_TYPE_PARAMS;
1414            m_parent->signalAPIResult(&result);
1415        }
1416        break;
1417    case QCAMERA_SM_EVT_PUT_PARAMS:
1418        {
1419            rc = m_parent->putParameters((char*)payload);
1420            result.status = rc;
1421            result.request_api = evt;
1422            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1423            m_parent->signalAPIResult(&result);
1424        }
1425        break;
1426    case QCAMERA_SM_EVT_STOP_PREVIEW:
1427        {
1428            // cancel picture first
1429            rc = m_parent->cancelPicture();
1430            m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
1431
1432            result.status = rc;
1433            result.request_api = evt;
1434            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1435            m_parent->signalAPIResult(&result);
1436        }
1437        break;
1438    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
1439        {
1440            rc = NO_ERROR;
1441            result.status = rc;
1442            result.request_api = evt;
1443            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1444            result.enabled = 0;
1445            m_parent->signalAPIResult(&result);
1446        }
1447        break;
1448    case QCAMERA_SM_EVT_RECORDING_ENABLED:
1449        {
1450            rc = NO_ERROR;
1451            result.status = rc;
1452            result.request_api = evt;
1453            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1454            result.enabled = 0;
1455            m_parent->signalAPIResult(&result);
1456        }
1457        break;
1458    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
1459        {
1460            rc = m_parent->storeMetaDataInBuffers(int(payload));
1461            result.status = rc;
1462            result.request_api = evt;
1463            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1464            m_parent->signalAPIResult(&result);
1465        }
1466        break;
1467    case QCAMERA_SM_EVT_DUMP:
1468        {
1469            rc = m_parent->dump((int)payload);
1470            result.status = rc;
1471            result.request_api = evt;
1472            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1473            m_parent->signalAPIResult(&result);
1474        }
1475        break;
1476    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
1477        {
1478            rc = m_parent->autoFocus();
1479            result.status = rc;
1480            result.request_api = evt;
1481            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1482            m_parent->signalAPIResult(&result);
1483        }
1484        break;
1485    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
1486        {
1487            rc = m_parent->cancelAutoFocus();
1488            result.status = rc;
1489            result.request_api = evt;
1490            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1491            m_parent->signalAPIResult(&result);
1492        }
1493        break;
1494    case QCAMERA_SM_EVT_SEND_COMMAND:
1495        {
1496            qcamera_sm_evt_command_payload_t *cmd_payload =
1497                (qcamera_sm_evt_command_payload_t *)payload;
1498            rc = m_parent->sendCommand(cmd_payload->cmd,
1499                                       cmd_payload->arg1,
1500                                       cmd_payload->arg2);
1501            result.status = rc;
1502            result.request_api = evt;
1503            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1504            m_parent->signalAPIResult(&result);
1505        }
1506        break;
1507    case QCAMERA_SM_EVT_CANCEL_PICTURE:
1508        {
1509            rc = m_parent->cancelPicture();
1510            m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
1511            result.status = rc;
1512            result.request_api = evt;
1513            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1514            m_parent->signalAPIResult(&result);
1515        }
1516        break;
1517    case QCAMERA_SM_EVT_REG_FACE_IMAGE:
1518        {
1519            int32_t faceID = 0;
1520            qcamera_sm_evt_reg_face_payload_t *reg_payload =
1521                (qcamera_sm_evt_reg_face_payload_t *)payload;
1522            rc = m_parent->registerFaceImage(reg_payload->img_ptr,
1523                                             reg_payload->config,
1524                                             faceID);
1525            result.status = rc;
1526            result.request_api = evt;
1527            result.result_type = QCAMERA_API_RESULT_TYPE_HANDLE;
1528            result.handle = faceID;
1529            m_parent->signalAPIResult(&result);
1530        }
1531        break;
1532    case QCAMERA_SM_EVT_TAKE_PICTURE:
1533    case QCAMERA_SM_EVT_START_RECORDING:
1534    case QCAMERA_SM_EVT_STOP_RECORDING:
1535    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
1536    case QCAMERA_SM_EVT_START_PREVIEW:
1537    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
1538    case QCAMERA_SM_EVT_RELEASE:
1539        {
1540            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1541            rc = INVALID_OPERATION;
1542            result.status = rc;
1543            result.request_api = evt;
1544            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1545            m_parent->signalAPIResult(&result);
1546        }
1547        break;
1548    case QCAMERA_SM_EVT_EVT_INTERNAL:
1549        {
1550            qcamera_sm_internal_evt_payload_t *internal_evt =
1551                (qcamera_sm_internal_evt_payload_t *)payload;
1552            switch (internal_evt->evt_type) {
1553            case QCAMERA_INTERNAL_EVT_FOCUS_UPDATE:
1554                rc = m_parent->processAutoFocusEvent(internal_evt->focus_data);
1555                break;
1556            default:
1557                break;
1558            }
1559        }
1560        break;
1561    case QCAMERA_SM_EVT_EVT_NOTIFY:
1562        {
1563            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
1564            switch (cam_evt->server_event_type) {
1565            case CAM_EVENT_TYPE_DAEMON_DIED:
1566                {
1567                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
1568                                            CAMERA_ERROR_SERVER_DIED,
1569                                            0);
1570                }
1571                break;
1572            default:
1573                ALOGD("%s: no handling for server evt (%d) at this state",
1574                      __func__, cam_evt->server_event_type);
1575                break;
1576            }
1577        }
1578        break;
1579    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
1580        {
1581            qcamera_jpeg_evt_payload_t *jpeg_job =
1582                (qcamera_jpeg_evt_payload_t *)payload;
1583            rc = m_parent->processJpegNotify(jpeg_job);
1584        }
1585        break;
1586    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
1587        {
1588            rc = m_parent->cancelPicture();
1589            m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
1590            result.status = rc;
1591            result.request_api = evt;
1592            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1593            m_parent->signalEvtResult(&result);
1594        }
1595        break;
1596    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
1597        {
1598            rc = m_parent->updateThermalLevel(
1599                    *(qcamera_thermal_level_enum_t *)&payload);
1600        }
1601        break;
1602    default:
1603        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1604        break;
1605    }
1606
1607    return rc;
1608}
1609
1610/*===========================================================================
1611 * FUNCTION   : procEvtRecordingState
1612 *
1613 * DESCRIPTION: finite state machine function to handle event in state of
1614 *              QCAMERA_SM_STATE_RECORDING.
1615 *
1616 * PARAMETERS :
1617 *   @evt      : event to be processed
1618 *   @payload  : event payload. Can be NULL if not needed.
1619 *
1620 * RETURN     : int32_t type of status
1621 *              NO_ERROR  -- success
1622 *              none-zero failure code
1623 *==========================================================================*/
1624int32_t QCameraStateMachine::procEvtRecordingState(qcamera_sm_evt_enum_t evt,
1625                                                   void *payload)
1626{
1627    int32_t rc = NO_ERROR;
1628    qcamera_api_result_t result;
1629    memset(&result, 0, sizeof(qcamera_api_result_t));
1630
1631    switch (evt) {
1632    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
1633        {
1634            // Error setting preview window during previewing
1635            ALOGE("Cannot set preview window when preview is running");
1636            rc = INVALID_OPERATION;
1637            result.status = rc;
1638            result.request_api = evt;
1639            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1640            m_parent->signalAPIResult(&result);
1641        }
1642        break;
1643    case QCAMERA_SM_EVT_SET_CALLBACKS:
1644        {
1645            qcamera_sm_evt_setcb_payload_t *setcbs =
1646                (qcamera_sm_evt_setcb_payload_t *)payload;
1647            rc = m_parent->setCallBacks(setcbs->notify_cb,
1648                                        setcbs->data_cb,
1649                                        setcbs->data_cb_timestamp,
1650                                        setcbs->get_memory,
1651                                        setcbs->user);
1652            result.status = rc;
1653            result.request_api = evt;
1654            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1655            m_parent->signalAPIResult(&result);
1656        }
1657        break;
1658    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
1659        {
1660            rc = m_parent->enableMsgType(int32_t(payload));
1661            result.status = rc;
1662            result.request_api = evt;
1663            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1664            m_parent->signalAPIResult(&result);
1665        }
1666        break;
1667    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
1668        {
1669            rc = m_parent->disableMsgType(int32_t(payload));
1670            result.status = rc;
1671            result.request_api = evt;
1672            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1673            m_parent->signalAPIResult(&result);
1674        }
1675        break;
1676    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
1677        {
1678            int enabled = m_parent->msgTypeEnabled(int32_t(payload));
1679            result.status = rc;
1680            result.request_api = evt;
1681            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1682            result.enabled = enabled;
1683            m_parent->signalAPIResult(&result);
1684        }
1685        break;
1686    case QCAMERA_SM_EVT_SET_PARAMS:
1687        {
1688            bool needRestart = false;
1689            rc = m_parent->updateParameters((char*)payload, needRestart);
1690            if (rc == NO_ERROR) {
1691                if (needRestart) {
1692                    // cannot set parameters that requires restart during recording
1693                    ALOGE("%s: Cannot set parameters that requires restart during recording",
1694                          __func__);
1695                    rc = BAD_VALUE;
1696                } else {
1697                    rc = m_parent->commitParameterChanges();
1698                }
1699            }
1700            result.status = rc;
1701            result.request_api = evt;
1702            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1703            m_parent->signalAPIResult(&result);
1704        }
1705        break;
1706    case QCAMERA_SM_EVT_GET_PARAMS:
1707        {
1708            result.params = m_parent->getParameters();
1709            rc = NO_ERROR;
1710            result.status = rc;
1711            result.request_api = evt;
1712            result.result_type = QCAMERA_API_RESULT_TYPE_PARAMS;
1713            m_parent->signalAPIResult(&result);
1714        }
1715        break;
1716    case QCAMERA_SM_EVT_PUT_PARAMS:
1717        {
1718            rc = m_parent->putParameters((char*)payload);
1719            result.status = rc;
1720            result.request_api = evt;
1721            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1722            m_parent->signalAPIResult(&result);
1723        }
1724        break;
1725    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
1726        {
1727            rc = NO_ERROR;
1728            result.status = rc;
1729            result.request_api = evt;
1730            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1731            result.enabled = 0;
1732            m_parent->signalAPIResult(&result);
1733        }
1734        break;
1735    case QCAMERA_SM_EVT_RECORDING_ENABLED:
1736        {
1737            rc = NO_ERROR;
1738            result.status = rc;
1739            result.request_api = evt;
1740            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1741            result.enabled = 1;
1742            m_parent->signalAPIResult(&result);
1743        }
1744        break;
1745    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
1746        {
1747            rc = m_parent->storeMetaDataInBuffers(int(payload));
1748            result.status = rc;
1749            result.request_api = evt;
1750            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1751            m_parent->signalAPIResult(&result);
1752        }
1753        break;
1754    case QCAMERA_SM_EVT_DUMP:
1755        {
1756            rc = m_parent->dump((int)payload);
1757            result.status = rc;
1758            result.request_api = evt;
1759            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1760            m_parent->signalAPIResult(&result);
1761        }
1762        break;
1763    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
1764        {
1765            rc = m_parent->autoFocus();
1766            result.status = rc;
1767            result.request_api = evt;
1768            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1769            m_parent->signalAPIResult(&result);
1770        }
1771        break;
1772    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
1773        {
1774            rc = m_parent->cancelAutoFocus();
1775            result.status = rc;
1776            result.request_api = evt;
1777            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1778            m_parent->signalAPIResult(&result);
1779        }
1780        break;
1781    case QCAMERA_SM_EVT_SEND_COMMAND:
1782        {
1783            qcamera_sm_evt_command_payload_t *cmd_payload =
1784                (qcamera_sm_evt_command_payload_t *)payload;
1785            rc = m_parent->sendCommand(cmd_payload->cmd,
1786                                       cmd_payload->arg1,
1787                                       cmd_payload->arg2);
1788            result.status = rc;
1789            result.request_api = evt;
1790            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1791            m_parent->signalAPIResult(&result);
1792        }
1793        break;
1794    case QCAMERA_SM_EVT_TAKE_PICTURE:
1795        {
1796            m_state = QCAMERA_SM_STATE_VIDEO_PIC_TAKING;
1797            rc = m_parent->takeLiveSnapshot();
1798            if (rc != NO_ERROR) {
1799                m_state = QCAMERA_SM_STATE_RECORDING;
1800            }
1801            result.status = rc;
1802            result.request_api = evt;
1803            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1804            m_parent->signalAPIResult(&result);
1805        }
1806        break;
1807    case QCAMERA_SM_EVT_START_RECORDING:
1808        {
1809            // no ops here
1810            ALOGD("%s: already in recording state, no ops for start_recording", __func__);
1811            rc = 0;
1812            result.status = rc;
1813            result.request_api = evt;
1814            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1815            m_parent->signalAPIResult(&result);
1816        }
1817        break;
1818    case QCAMERA_SM_EVT_STOP_RECORDING:
1819        {
1820            rc = m_parent->stopRecording();
1821            m_state = QCAMERA_SM_STATE_PREVIEWING;
1822            result.status = rc;
1823            result.request_api = evt;
1824            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1825            m_parent->signalAPIResult(&result);
1826        }
1827        break;
1828    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
1829        {
1830            rc = m_parent->releaseRecordingFrame((const void *)payload);
1831            result.status = rc;
1832            result.request_api = evt;
1833            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1834            m_parent->signalAPIResult(&result);
1835        }
1836        break;
1837    case QCAMERA_SM_EVT_REG_FACE_IMAGE:
1838        {
1839            int32_t faceID = 0;
1840            qcamera_sm_evt_reg_face_payload_t *reg_payload =
1841                (qcamera_sm_evt_reg_face_payload_t *)payload;
1842            rc = m_parent->registerFaceImage(reg_payload->img_ptr,
1843                                             reg_payload->config,
1844                                             faceID);
1845            result.status = rc;
1846            result.request_api = evt;
1847            result.result_type = QCAMERA_API_RESULT_TYPE_HANDLE;
1848            result.handle = faceID;
1849            m_parent->signalAPIResult(&result);
1850        }
1851        break;
1852    case QCAMERA_SM_EVT_PREPARE_SNAPSHOT:
1853        {
1854            //In Video snapshot, prepare hardware is a no-op.
1855            result.status = NO_ERROR;
1856            result.request_api = evt;
1857            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1858            m_parent->signalAPIResult(&result);
1859        }
1860        break;
1861    case QCAMERA_SM_EVT_CANCEL_PICTURE:
1862    case QCAMERA_SM_EVT_START_PREVIEW:
1863    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
1864    case QCAMERA_SM_EVT_STOP_PREVIEW:
1865    case QCAMERA_SM_EVT_RELEASE:
1866        {
1867            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1868            rc = INVALID_OPERATION;
1869            result.status = rc;
1870            result.request_api = evt;
1871            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1872            m_parent->signalAPIResult(&result);
1873        }
1874        break;
1875    case QCAMERA_SM_EVT_EVT_INTERNAL:
1876        {
1877            qcamera_sm_internal_evt_payload_t *internal_evt =
1878                (qcamera_sm_internal_evt_payload_t *)payload;
1879            switch (internal_evt->evt_type) {
1880            case QCAMERA_INTERNAL_EVT_FOCUS_UPDATE:
1881                rc = m_parent->processAutoFocusEvent(internal_evt->focus_data);
1882                break;
1883            default:
1884                break;
1885            }
1886        }
1887        break;
1888    case QCAMERA_SM_EVT_EVT_NOTIFY:
1889        {
1890            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
1891            switch (cam_evt->server_event_type) {
1892            case CAM_EVENT_TYPE_DAEMON_DIED:
1893                {
1894                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
1895                                            CAMERA_ERROR_SERVER_DIED,
1896                                            0);
1897                }
1898                break;
1899            default:
1900                ALOGE("%s: Invalid internal event %d in state(%d)",
1901                            __func__, cam_evt->server_event_type, m_state);
1902                break;
1903            }
1904        }
1905        break;
1906    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
1907        {
1908            rc = m_parent->updateThermalLevel(
1909                    *(qcamera_thermal_level_enum_t *)&payload);
1910        }
1911        break;
1912    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
1913    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
1914    default:
1915        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
1916        break;
1917    }
1918
1919    return rc;
1920}
1921
1922/*===========================================================================
1923 * FUNCTION   : procEvtVideoPicTakingState
1924 *
1925 * DESCRIPTION: finite state machine function to handle event in state of
1926 *              QCAMERA_SM_STATE_VIDEO_PIC_TAKING.
1927 *
1928 * PARAMETERS :
1929 *   @evt      : event to be processed
1930 *   @payload  : event payload. Can be NULL if not needed.
1931 *
1932 * RETURN     : int32_t type of status
1933 *              NO_ERROR  -- success
1934 *              none-zero failure code
1935 *==========================================================================*/
1936int32_t QCameraStateMachine::procEvtVideoPicTakingState(qcamera_sm_evt_enum_t evt,
1937                                                        void *payload)
1938{
1939    int32_t rc = NO_ERROR;
1940    qcamera_api_result_t result;
1941    memset(&result, 0, sizeof(qcamera_api_result_t));
1942
1943    switch (evt) {
1944    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
1945        {
1946            // Error setting preview window during previewing
1947            ALOGE("Cannot set preview window when preview is running");
1948            rc = INVALID_OPERATION;
1949            result.status = rc;
1950            result.request_api = evt;
1951            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1952            m_parent->signalAPIResult(&result);
1953        }
1954        break;
1955    case QCAMERA_SM_EVT_SET_CALLBACKS:
1956        {
1957            qcamera_sm_evt_setcb_payload_t *setcbs =
1958                (qcamera_sm_evt_setcb_payload_t *)payload;
1959            rc = m_parent->setCallBacks(setcbs->notify_cb,
1960                                        setcbs->data_cb,
1961                                        setcbs->data_cb_timestamp,
1962                                        setcbs->get_memory,
1963                                        setcbs->user);
1964            result.status = rc;
1965            result.request_api = evt;
1966            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1967            m_parent->signalAPIResult(&result);
1968        }
1969        break;
1970    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
1971        {
1972            rc = m_parent->enableMsgType(int32_t(payload));
1973            result.status = rc;
1974            result.request_api = evt;
1975            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1976            m_parent->signalAPIResult(&result);
1977        }
1978        break;
1979    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
1980        {
1981            rc = m_parent->disableMsgType(int32_t(payload));
1982            result.status = rc;
1983            result.request_api = evt;
1984            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
1985            m_parent->signalAPIResult(&result);
1986        }
1987        break;
1988    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
1989        {
1990            int enabled = m_parent->msgTypeEnabled(int32_t(payload));
1991            result.status = rc;
1992            result.request_api = evt;
1993            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
1994            result.enabled = enabled;
1995            m_parent->signalAPIResult(&result);
1996        }
1997        break;
1998    case QCAMERA_SM_EVT_SET_PARAMS:
1999        {
2000            bool needRestart = false;
2001            rc = m_parent->updateParameters((char*)payload, needRestart);
2002            if (rc == NO_ERROR) {
2003                if (needRestart) {
2004                    // cannot set parameters that requires restart during recording
2005                    ALOGE("%s: Cannot set parameters that requires restart during recording",
2006                          __func__);
2007                    rc = BAD_VALUE;
2008                } else {
2009                    rc = m_parent->commitParameterChanges();
2010                }
2011            }
2012            result.status = rc;
2013            result.request_api = evt;
2014            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2015            m_parent->signalAPIResult(&result);
2016        }
2017        break;
2018    case QCAMERA_SM_EVT_GET_PARAMS:
2019        {
2020            result.params = m_parent->getParameters();
2021            rc = NO_ERROR;
2022            result.status = rc;
2023            result.request_api = evt;
2024            result.result_type = QCAMERA_API_RESULT_TYPE_PARAMS;
2025            m_parent->signalAPIResult(&result);
2026        }
2027        break;
2028    case QCAMERA_SM_EVT_PUT_PARAMS:
2029        {
2030            rc = m_parent->putParameters((char*)payload);
2031            result.status = rc;
2032            result.request_api = evt;
2033            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2034            m_parent->signalAPIResult(&result);
2035        }
2036        break;
2037    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
2038        {
2039            rc = NO_ERROR;
2040            result.status = rc;
2041            result.request_api = evt;
2042            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
2043            result.enabled = 1;
2044            m_parent->signalAPIResult(&result);
2045        }
2046        break;
2047    case QCAMERA_SM_EVT_RECORDING_ENABLED:
2048        {
2049            rc = NO_ERROR;
2050            result.status = rc;
2051            result.request_api = evt;
2052            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
2053            result.enabled = 1;
2054            m_parent->signalAPIResult(&result);
2055        }
2056        break;
2057    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
2058        {
2059            rc = m_parent->storeMetaDataInBuffers(int(payload));
2060            result.status = rc;
2061            result.request_api = evt;
2062            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2063            m_parent->signalAPIResult(&result);
2064        }
2065        break;
2066    case QCAMERA_SM_EVT_DUMP:
2067        {
2068            rc = m_parent->dump((int)payload);
2069            result.status = rc;
2070            result.request_api = evt;
2071            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2072            m_parent->signalAPIResult(&result);
2073        }
2074        break;
2075    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
2076        {
2077            rc = m_parent->autoFocus();
2078            result.status = rc;
2079            result.request_api = evt;
2080            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2081            m_parent->signalAPIResult(&result);
2082        }
2083        break;
2084    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
2085        {
2086            rc = m_parent->cancelAutoFocus();
2087            result.status = rc;
2088            result.request_api = evt;
2089            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2090            m_parent->signalAPIResult(&result);
2091        }
2092        break;
2093    case QCAMERA_SM_EVT_SEND_COMMAND:
2094        {
2095            qcamera_sm_evt_command_payload_t *cmd_payload =
2096                (qcamera_sm_evt_command_payload_t *)payload;
2097            rc = m_parent->sendCommand(cmd_payload->cmd,
2098                                       cmd_payload->arg1,
2099                                       cmd_payload->arg2);
2100            result.status = rc;
2101            result.request_api = evt;
2102            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2103            m_parent->signalAPIResult(&result);
2104        }
2105        break;
2106    case QCAMERA_SM_EVT_STOP_RECORDING:
2107        {
2108            rc = m_parent->stopRecording();
2109            m_state = QCAMERA_SM_STATE_PREVIEW_PIC_TAKING;
2110            result.status = rc;
2111            result.request_api = evt;
2112            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2113            m_parent->signalAPIResult(&result);
2114        }
2115        break;
2116    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
2117        {
2118            rc = m_parent->releaseRecordingFrame((const void *)payload);
2119            result.status = rc;
2120            result.request_api = evt;
2121            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2122            m_parent->signalAPIResult(&result);
2123        }
2124        break;
2125    case QCAMERA_SM_EVT_CANCEL_PICTURE:
2126        {
2127            rc = m_parent->cancelLiveSnapshot();
2128            m_state = QCAMERA_SM_STATE_RECORDING;
2129            result.status = rc;
2130            result.request_api = evt;
2131            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2132            m_parent->signalAPIResult(&result);
2133        }
2134        break;
2135    case QCAMERA_SM_EVT_REG_FACE_IMAGE:
2136        {
2137            int32_t faceID = 0;
2138            qcamera_sm_evt_reg_face_payload_t *reg_payload =
2139                (qcamera_sm_evt_reg_face_payload_t *)payload;
2140            rc = m_parent->registerFaceImage(reg_payload->img_ptr,
2141                                             reg_payload->config,
2142                                             faceID);
2143            result.status = rc;
2144            result.request_api = evt;
2145            result.result_type = QCAMERA_API_RESULT_TYPE_HANDLE;
2146            result.handle = faceID;
2147            m_parent->signalAPIResult(&result);
2148        }
2149        break;
2150    case QCAMERA_SM_EVT_START_RECORDING:
2151    case QCAMERA_SM_EVT_START_PREVIEW:
2152    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
2153    case QCAMERA_SM_EVT_STOP_PREVIEW:
2154    case QCAMERA_SM_EVT_TAKE_PICTURE:
2155    case QCAMERA_SM_EVT_RELEASE:
2156        {
2157            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
2158            rc = INVALID_OPERATION;
2159            result.status = rc;
2160            result.request_api = evt;
2161            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2162            m_parent->signalAPIResult(&result);
2163        }
2164        break;
2165    case QCAMERA_SM_EVT_EVT_INTERNAL:
2166        {
2167            qcamera_sm_internal_evt_payload_t *internal_evt =
2168                (qcamera_sm_internal_evt_payload_t *)payload;
2169            switch (internal_evt->evt_type) {
2170            case QCAMERA_INTERNAL_EVT_FOCUS_UPDATE:
2171                rc = m_parent->processAutoFocusEvent(internal_evt->focus_data);
2172                break;
2173            default:
2174                break;
2175            }
2176        }
2177        break;
2178    case QCAMERA_SM_EVT_EVT_NOTIFY:
2179        {
2180            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
2181            switch (cam_evt->server_event_type) {
2182            case CAM_EVENT_TYPE_DAEMON_DIED:
2183                {
2184                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
2185                                            CAMERA_ERROR_SERVER_DIED,
2186                                            0);
2187                }
2188                break;
2189            default:
2190                ALOGE("%s: Invalid internal event %d in state(%d)",
2191                            __func__, cam_evt->server_event_type, m_state);
2192                break;
2193            }
2194        }
2195        break;
2196    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
2197        {
2198            qcamera_jpeg_evt_payload_t *jpeg_job =
2199                (qcamera_jpeg_evt_payload_t *)payload;
2200            rc = m_parent->processJpegNotify(jpeg_job);
2201        }
2202        break;
2203    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
2204        {
2205            rc = m_parent->cancelLiveSnapshot();
2206            m_state = QCAMERA_SM_STATE_RECORDING;
2207            result.status = rc;
2208            result.request_api = evt;
2209            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2210            m_parent->signalEvtResult(&result);
2211        }
2212        break;
2213    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
2214        {
2215            rc = m_parent->updateThermalLevel(
2216                    *(qcamera_thermal_level_enum_t *)&payload);
2217        }
2218        break;
2219    default:
2220        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
2221        break;
2222    }
2223
2224    return rc;
2225}
2226
2227/*===========================================================================
2228 * FUNCTION   : procEvtPreviewPicTakingState
2229 *
2230 * DESCRIPTION: finite state machine function to handle event in state of
2231 *              QCAMERA_SM_STATE_PREVIEW_PIC_TAKING.
2232 *
2233 * PARAMETERS :
2234 *   @evt      : event to be processed
2235 *   @payload  : event payload. Can be NULL if not needed.
2236 *
2237 * RETURN     : int32_t type of status
2238 *              NO_ERROR  -- success
2239 *              none-zero failure code
2240 *==========================================================================*/
2241int32_t QCameraStateMachine::procEvtPreviewPicTakingState(qcamera_sm_evt_enum_t evt,
2242                                                          void *payload)
2243{
2244    int32_t rc = NO_ERROR;
2245    qcamera_api_result_t result;
2246    memset(&result, 0, sizeof(qcamera_api_result_t));
2247
2248    switch (evt) {
2249    case QCAMERA_SM_EVT_SET_CALLBACKS:
2250        {
2251            qcamera_sm_evt_setcb_payload_t *setcbs =
2252                (qcamera_sm_evt_setcb_payload_t *)payload;
2253            rc = m_parent->setCallBacks(setcbs->notify_cb,
2254                                        setcbs->data_cb,
2255                                        setcbs->data_cb_timestamp,
2256                                        setcbs->get_memory,
2257                                        setcbs->user);
2258            result.status = rc;
2259            result.request_api = evt;
2260            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2261            m_parent->signalAPIResult(&result);
2262        }
2263        break;
2264    case QCAMERA_SM_EVT_ENABLE_MSG_TYPE:
2265        {
2266            rc = m_parent->enableMsgType(int32_t(payload));
2267            result.status = rc;
2268            result.request_api = evt;
2269            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2270            m_parent->signalAPIResult(&result);
2271        }
2272        break;
2273    case QCAMERA_SM_EVT_DISABLE_MSG_TYPE:
2274        {
2275            rc = m_parent->disableMsgType(int32_t(payload));
2276            result.status = rc;
2277            result.request_api = evt;
2278            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2279            m_parent->signalAPIResult(&result);
2280        }
2281        break;
2282    case QCAMERA_SM_EVT_MSG_TYPE_ENABLED:
2283        {
2284            int enabled = m_parent->msgTypeEnabled(int32_t(payload));
2285            result.status = rc;
2286            result.request_api = evt;
2287            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
2288            result.enabled = enabled;
2289            m_parent->signalAPIResult(&result);
2290        }
2291        break;
2292    case QCAMERA_SM_EVT_SET_PARAMS:
2293        {
2294            bool needRestart = false;
2295            rc = m_parent->updateParameters((char*)payload, needRestart);
2296            if (rc == NO_ERROR) {
2297                if (needRestart) {
2298                    // need restart preview for parameters to take effect
2299                    // stop preview
2300                    m_parent->stopPreview();
2301                    // commit parameter changes to server
2302                    m_parent->commitParameterChanges();
2303                    // start preview again
2304                    rc = m_parent->preparePreview();
2305                    if (rc == NO_ERROR) {
2306                        rc = m_parent->startPreview();
2307                        if (rc != NO_ERROR) {
2308                            m_parent->unpreparePreview();
2309                        }
2310                    }
2311                    if (rc != NO_ERROR) {
2312                        m_state = QCAMERA_SM_STATE_PIC_TAKING;
2313                    }
2314                } else {
2315                    rc = m_parent->commitParameterChanges();
2316                }
2317            }
2318            result.status = rc;
2319            result.request_api = evt;
2320            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2321            m_parent->signalAPIResult(&result);
2322        }
2323        break;
2324    case QCAMERA_SM_EVT_GET_PARAMS:
2325        {
2326            result.params = m_parent->getParameters();
2327            rc = NO_ERROR;
2328            result.status = rc;
2329            result.request_api = evt;
2330            result.result_type = QCAMERA_API_RESULT_TYPE_PARAMS;
2331            m_parent->signalAPIResult(&result);
2332        }
2333        break;
2334    case QCAMERA_SM_EVT_PUT_PARAMS:
2335        {
2336            rc = m_parent->putParameters((char*)payload);
2337            result.status = rc;
2338            result.request_api = evt;
2339            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2340            m_parent->signalAPIResult(&result);
2341        }
2342        break;
2343    case QCAMERA_SM_EVT_PREVIEW_ENABLED:
2344        {
2345            rc = NO_ERROR;
2346            result.status = rc;
2347            result.request_api = evt;
2348            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
2349            result.enabled = 1;
2350            m_parent->signalAPIResult(&result);
2351        }
2352        break;
2353    case QCAMERA_SM_EVT_RECORDING_ENABLED:
2354        {
2355            rc = NO_ERROR;
2356            result.status = rc;
2357            result.request_api = evt;
2358            result.result_type = QCAMERA_API_RESULT_TYPE_ENABLE_FLAG;
2359            result.enabled = 0;
2360            m_parent->signalAPIResult(&result);
2361        }
2362        break;
2363    case QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS:
2364        {
2365            rc = m_parent->storeMetaDataInBuffers(int(payload));
2366            result.status = rc;
2367            result.request_api = evt;
2368            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2369            m_parent->signalAPIResult(&result);
2370        }
2371        break;
2372    case QCAMERA_SM_EVT_DUMP:
2373        {
2374            rc = m_parent->dump((int)payload);
2375            result.status = rc;
2376            result.request_api = evt;
2377            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2378            m_parent->signalAPIResult(&result);
2379        }
2380        break;
2381    case QCAMERA_SM_EVT_START_AUTO_FOCUS:
2382        {
2383            rc = m_parent->autoFocus();
2384            result.status = rc;
2385            result.request_api = evt;
2386            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2387            m_parent->signalAPIResult(&result);
2388        }
2389        break;
2390    case QCAMERA_SM_EVT_STOP_AUTO_FOCUS:
2391        {
2392            rc = m_parent->cancelAutoFocus();
2393            result.status = rc;
2394            result.request_api = evt;
2395            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2396            m_parent->signalAPIResult(&result);
2397        }
2398        break;
2399    case QCAMERA_SM_EVT_SEND_COMMAND:
2400        {
2401            qcamera_sm_evt_command_payload_t *cmd_payload =
2402                (qcamera_sm_evt_command_payload_t *)payload;
2403            rc = m_parent->sendCommand(cmd_payload->cmd,
2404                                       cmd_payload->arg1,
2405                                       cmd_payload->arg2);
2406            result.status = rc;
2407            result.request_api = evt;
2408            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2409            m_parent->signalAPIResult(&result);
2410        }
2411        break;
2412    case QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME:
2413        {
2414            rc = m_parent->releaseRecordingFrame((const void *)payload);
2415            result.status = rc;
2416            result.request_api = evt;
2417            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2418            m_parent->signalAPIResult(&result);
2419        }
2420        break;
2421    case QCAMERA_SM_EVT_CANCEL_PICTURE:
2422        {
2423            if (m_parent->isZSLMode()) {
2424                rc = m_parent->cancelPicture();
2425            } else {
2426                rc = m_parent->cancelLiveSnapshot();
2427            }
2428            m_state = QCAMERA_SM_STATE_PREVIEWING;
2429            result.status = rc;
2430            result.request_api = evt;
2431            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2432            m_parent->signalAPIResult(&result);
2433        }
2434        break;
2435    case QCAMERA_SM_EVT_STOP_PREVIEW:
2436        {
2437            if (m_parent->isZSLMode()) {
2438                // cancel picture first
2439                rc = m_parent->cancelPicture();
2440                m_parent->stopChannel(QCAMERA_CH_TYPE_ZSL);
2441            } else {
2442                rc = m_parent->cancelLiveSnapshot();
2443                m_parent->stopChannel(QCAMERA_CH_TYPE_PREVIEW);
2444            }
2445            // unprepare preview
2446            m_parent->unpreparePreview();
2447            m_state = QCAMERA_SM_STATE_PREVIEW_STOPPED;
2448            result.status = rc;
2449            result.request_api = evt;
2450            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2451            m_parent->signalAPIResult(&result);
2452        }
2453        break;
2454    case QCAMERA_SM_EVT_START_RECORDING:
2455        {
2456            rc = m_parent->stopRecording();
2457            if (rc == NO_ERROR) {
2458                m_state = QCAMERA_SM_STATE_VIDEO_PIC_TAKING;
2459            }
2460            result.status = rc;
2461            result.request_api = evt;
2462            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2463            m_parent->signalAPIResult(&result);
2464        }
2465        break;
2466    case QCAMERA_SM_EVT_REG_FACE_IMAGE:
2467        {
2468            int32_t faceID = 0;
2469            qcamera_sm_evt_reg_face_payload_t *reg_payload =
2470                (qcamera_sm_evt_reg_face_payload_t *)payload;
2471            rc = m_parent->registerFaceImage(reg_payload->img_ptr,
2472                                             reg_payload->config,
2473                                             faceID);
2474            result.status = rc;
2475            result.request_api = evt;
2476            result.result_type = QCAMERA_API_RESULT_TYPE_HANDLE;
2477            result.handle = faceID;
2478            m_parent->signalAPIResult(&result);
2479        }
2480        break;
2481    case QCAMERA_SM_EVT_STOP_RECORDING:
2482    case QCAMERA_SM_EVT_START_PREVIEW:
2483    case QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW:
2484    case QCAMERA_SM_EVT_TAKE_PICTURE:
2485    case QCAMERA_SM_EVT_SET_PREVIEW_WINDOW:
2486    case QCAMERA_SM_EVT_RELEASE:
2487        {
2488            ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
2489            rc = INVALID_OPERATION;
2490            result.status = rc;
2491            result.request_api = evt;
2492            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2493            m_parent->signalAPIResult(&result);
2494        }
2495        break;
2496    case QCAMERA_SM_EVT_EVT_INTERNAL:
2497        {
2498            qcamera_sm_internal_evt_payload_t *internal_evt =
2499                (qcamera_sm_internal_evt_payload_t *)payload;
2500            switch (internal_evt->evt_type) {
2501            case QCAMERA_INTERNAL_EVT_FOCUS_UPDATE:
2502                rc = m_parent->processAutoFocusEvent(internal_evt->focus_data);
2503                break;
2504            default:
2505                break;
2506            }
2507        }
2508        break;
2509    case QCAMERA_SM_EVT_EVT_NOTIFY:
2510        {
2511            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
2512            switch (cam_evt->server_event_type) {
2513            case CAM_EVENT_TYPE_DAEMON_DIED:
2514                {
2515                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
2516                                            CAMERA_ERROR_SERVER_DIED,
2517                                            0);
2518                }
2519                break;
2520            default:
2521                ALOGE("%s: Invalid internal event %d in state(%d)",
2522                            __func__, cam_evt->server_event_type, m_state);
2523                break;
2524            }
2525        }
2526        break;
2527    case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
2528        {
2529            qcamera_jpeg_evt_payload_t *jpeg_job =
2530                (qcamera_jpeg_evt_payload_t *)payload;
2531            rc = m_parent->processJpegNotify(jpeg_job);
2532        }
2533        break;
2534    case QCAMERA_SM_EVT_SNAPSHOT_DONE:
2535        {
2536            if (m_parent->isZSLMode()) {
2537                rc = m_parent->cancelPicture();
2538            } else {
2539                rc = m_parent->cancelLiveSnapshot();
2540            }
2541            m_state = QCAMERA_SM_STATE_PREVIEWING;
2542            result.status = rc;
2543            result.request_api = evt;
2544            result.result_type = QCAMERA_API_RESULT_TYPE_DEF;
2545            m_parent->signalEvtResult(&result);
2546        }
2547        break;
2548    case QCAMERA_SM_EVT_THERMAL_NOTIFY:
2549        {
2550            rc = m_parent->updateThermalLevel(
2551                    *(qcamera_thermal_level_enum_t *)&payload);
2552        }
2553        break;
2554    default:
2555        ALOGE("%s: cannot handle evt(%d) in state(%d)", __func__, evt, m_state);
2556        break;
2557    }
2558
2559    return rc;
2560}
2561
2562/*===========================================================================
2563 * FUNCTION   : isPreviewRunning
2564 *
2565 * DESCRIPTION: check if preview is in process.
2566 *
2567 * PARAMETERS : None
2568 *
2569 * RETURN     : true -- preview running
2570 *              false -- preview stopped
2571 *==========================================================================*/
2572bool QCameraStateMachine::isPreviewRunning()
2573{
2574    switch (m_state) {
2575    case QCAMERA_SM_STATE_PREVIEWING:
2576    case QCAMERA_SM_STATE_RECORDING:
2577    case QCAMERA_SM_STATE_VIDEO_PIC_TAKING:
2578    case QCAMERA_SM_STATE_PREVIEW_PIC_TAKING:
2579    case QCAMERA_SM_STATE_PREPARE_SNAPSHOT:
2580        return true;
2581    default:
2582        return false;
2583    }
2584}
2585
2586}; // namespace qcamera
2587