QCamera2: Updates camera error handling

- This patch propagates an additional V4L2
  error event to the camera client via
  error callbacks.

Change-Id: I767060496c8e8e1e8936ec185a9560a83f3fb6d5
diff --git a/QCamera2/HAL/QCameraStateMachine.cpp b/QCamera2/HAL/QCameraStateMachine.cpp
index 3fc050d..c34291d 100644
--- a/QCamera2/HAL/QCameraStateMachine.cpp
+++ b/QCamera2/HAL/QCameraStateMachine.cpp
@@ -534,8 +534,26 @@
             m_parent->signalAPIResult(&result);
         }
         break;
-    case QCAMERA_SM_EVT_EVT_INTERNAL:
     case QCAMERA_SM_EVT_EVT_NOTIFY:
+        {
+            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
+            switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
+            default:
+                ALOGE("%s: Invalid internal event %d in state(%d)",
+                            __func__, cam_evt->server_event_type, m_state);
+                break;
+            }
+        }
+        break;
+    case QCAMERA_SM_EVT_EVT_INTERNAL:
     case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
     case QCAMERA_SM_EVT_SNAPSHOT_DONE:
     case QCAMERA_SM_EVT_THERMAL_NOTIFY:
@@ -798,8 +816,26 @@
             m_parent->signalAPIResult(&result);
         }
         break;
-    case QCAMERA_SM_EVT_EVT_INTERNAL:
     case QCAMERA_SM_EVT_EVT_NOTIFY:
+        {
+            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
+            switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
+            default:
+                ALOGE("%s: Invalid internal event %d in state(%d)",
+                            __func__, cam_evt->server_event_type, m_state);
+                break;
+            }
+        }
+        break;
+    case QCAMERA_SM_EVT_EVT_INTERNAL:
     case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
     case QCAMERA_SM_EVT_SNAPSHOT_DONE:
     case QCAMERA_SM_EVT_THERMAL_NOTIFY:
@@ -1128,6 +1164,14 @@
         {
             mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
             switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
             default:
                 ALOGD("%s: no handling for server evt (%d) at this state",
                       __func__, cam_evt->server_event_type);
@@ -1230,6 +1274,24 @@
         }
         break;
     case QCAMERA_SM_EVT_EVT_NOTIFY:
+        {
+            mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
+            switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
+            default:
+                ALOGE("%s: Invalid internal event %d in state(%d)",
+                            __func__, cam_evt->server_event_type, m_state);
+                break;
+            }
+        }
+        break;
     case QCAMERA_SM_EVT_THERMAL_NOTIFY:
     case QCAMERA_SM_EVT_JPEG_EVT_NOTIFY:
     case QCAMERA_SM_EVT_SNAPSHOT_DONE:
@@ -1488,6 +1550,14 @@
         {
             mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
             switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
             default:
                 ALOGD("%s: no handling for server evt (%d) at this state",
                       __func__, cam_evt->server_event_type);
@@ -1799,9 +1869,17 @@
         {
             mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
             switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
             default:
-                ALOGD("%s: no handling for server evt (%d) at this state",
-                      __func__, cam_evt->server_event_type);
+                ALOGE("%s: Invalid internal event %d in state(%d)",
+                            __func__, cam_evt->server_event_type, m_state);
                 break;
             }
         }
@@ -2082,9 +2160,17 @@
         {
             mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
             switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
             default:
-                ALOGD("%s: no handling for server evt (%d) at this state",
-                      __func__, cam_evt->server_event_type);
+                ALOGE("%s: Invalid internal event %d in state(%d)",
+                            __func__, cam_evt->server_event_type, m_state);
                 break;
             }
         }
@@ -2402,9 +2488,17 @@
         {
             mm_camera_event_t *cam_evt = (mm_camera_event_t *)payload;
             switch (cam_evt->server_event_type) {
+            case CAM_EVENT_TYPE_DAEMON_DIED:
+                {
+                    free(payload);
+                    m_parent->sendEvtNotify(CAMERA_MSG_ERROR,
+                                            CAMERA_ERROR_SERVER_DIED,
+                                            0);
+                }
+                break;
             default:
-                ALOGD("%s: no handling for server evt (%d) at this state",
-                      __func__, cam_evt->server_event_type);
+                ALOGE("%s: Invalid internal event %d in state(%d)",
+                            __func__, cam_evt->server_event_type, m_state);
                 break;
             }
         }
diff --git a/QCamera2/stack/common/cam_types.h b/QCamera2/stack/common/cam_types.h
index dba418f..da9b0db 100644
--- a/QCamera2/stack/common/cam_types.h
+++ b/QCamera2/stack/common/cam_types.h
@@ -457,6 +457,7 @@
     CAM_EVENT_TYPE_MAP_UNMAP_DONE  = (1<<0),
     CAM_EVENT_TYPE_AUTO_FOCUS_DONE = (1<<1),
     CAM_EVENT_TYPE_ZOOM_DONE       = (1<<2),
+    CAM_EVENT_TYPE_DAEMON_DIED     = (1<<3),
     CAM_EVENT_TYPE_MAX
 } cam_event_type_t;
 
diff --git a/QCamera2/stack/mm-camera-interface/src/mm_camera.c b/QCamera2/stack/mm-camera-interface/src/mm_camera.c
index deac8b8..de72ba2 100644
--- a/QCamera2/stack/mm-camera-interface/src/mm_camera.c
+++ b/QCamera2/stack/mm-camera-interface/src/mm_camera.c
@@ -134,6 +134,7 @@
         }
         pthread_mutex_unlock(&my_obj->cb_lock);
     }
+    free(cmd_cb);
 }
 
 /*===========================================================================
@@ -152,7 +153,8 @@
     struct v4l2_event ev;
     struct msm_v4l2_event_data *msm_evt = NULL;
     int rc;
-    mm_camera_cmdcb_t *node = NULL;
+    mm_camera_event_t evt;
+    memset(&evt, 0, sizeof(mm_camera_event_t));
 
     mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
     if (NULL != my_obj) {
@@ -170,15 +172,15 @@
                 pthread_cond_signal(&my_obj->evt_cond);
                 pthread_mutex_unlock(&my_obj->evt_lock);
                 break;
+            case MSM_CAMERA_PRIV_SHUTDOWN:
+                {
+                    evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
+                    mm_camera_enqueue_evt(my_obj, &evt);
+                }
+                break;
             default:
                 break;
             }
-            if (NULL != node) {
-                /* enqueue to evt cmd thread */
-                cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
-                /* wake up evt cmd thread */
-                cam_sem_post(&(my_obj->evt_thread.cmd_sem));
-            }
         }
     }
 }