Revise shutdown command function 99/292699/4
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 11 May 2023 07:27:16 +0000 (16:27 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Fri, 12 May 2023 09:08:19 +0000 (18:08 +0900)
- Previously, camera_stop_preview() and camera_destroy() in shutdown command function could be failed
  when camera_stop_preview() is already executing in task thread by client's request at the same time.
- This patch adds new job to stop preview for shutdown command
  and it prevents to execute camera_stop_preview() in shutdown command and task thread concurrently.

[Version] 0.3.60
[Issue Type] Improvement

Change-Id: I851821788a2c8a8c3c83d6f8155833a4f234b1ef
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
muse/include/muse_camera.h
muse/src/muse_camera_dispatcher.c
packaging/mmsvc-camera.spec

index fa43a3b..f3ad56a 100644 (file)
@@ -223,6 +223,7 @@ typedef enum {
        MUSE_CAMERA_API_ATTR_GET_WHITEBALANCE_TEMPERATURE, /* 185 */
        MUSE_CAMERA_API_ATTR_GET_WHITEBALANCE_TEMPERATURE_RANGE,
        MUSE_CAMERA_API_ATTR_GET_WHITEBALANCE_TEMPERATURE_STEP,
+       MUSE_CAMERA_API_FORCE_STOP, /* This is not used for client. */
        MUSE_CAMERA_API_MAX
 } muse_camera_api_e;
 
index e3b455d..70b1523 100644 (file)
 #define MUSED_KEY_FLASH_STATE_CHECK   "camera_get_flash_state_is_called"
 #define MUSED_KEY_FLASH_STATE_RETURN  "camera_get_flash_state_return"
 #define MUSED_KEY_FLASH_STATE_COUNT   "camera_get_flash_state_count"
+#define MUSED_CAMERA_WAIT_TIME_IN_USED      3000 /* ms */
+#define MUSED_CAMERA_WAIT_TIME_FORCE_STOP   5000 /* ms */
+#define MUSED_CAMERA_WAIT_TIME_CAPTURE      (100 * 1000) /* us */
+#define MUSED_CAMERA_WAIT_CAPTURE_TRY_MAX   30
 
 #define camera_return_if_fail(expr) \
        do { \
@@ -1139,6 +1143,45 @@ static void _camera_task_add_job(muse_camera_handle_s *muse_camera, int api, int
 }
 
 
+static int __camera_force_stop(muse_camera_handle_s *muse_camera)
+{
+       int capture_try_count = 0;
+       int ret = CAMERA_ERROR_NONE;
+       camera_state_e state = CAMERA_STATE_NONE;
+
+       camera_return_val_if_fail(muse_camera, CAMERA_ERROR_INVALID_PARAMETER);
+
+retry:
+       legacy_camera_get_state(muse_camera->camera_handle, &state);
+
+       CAM_LOG_WARNING("current state[%d]", state);
+
+       switch (state) {
+       case CAMERA_STATE_CAPTURING:
+               if (capture_try_count++ < MUSED_CAMERA_WAIT_CAPTURE_TRY_MAX) {
+                       CAM_LOG_WARNING("now capturing.. wait for capture data...");
+                       usleep(MUSED_CAMERA_WAIT_TIME_CAPTURE);
+                       goto retry;
+               }
+               CAM_LOG_ERROR("wait capture data timeout! keep going...");
+               /* fall through */
+       case CAMERA_STATE_CAPTURED:
+               ret = legacy_camera_start_preview(muse_camera->camera_handle);
+               CAM_LOG_WARNING("start preview after capture[0x%x]", ret);
+               /* fall through */
+       case CAMERA_STATE_PREVIEW:
+               camera_remove_export_data(&muse_camera->camera_data, -1); /* force return buffer before stop preview */
+               ret = legacy_camera_stop_preview(muse_camera->camera_handle);
+               CAM_LOG_WARNING("stop preview[0x%x]", ret);
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+
 static void __camera_task_process_job(muse_camera_handle_s *muse_camera, muse_camera_task_job_s *job)
 {
        int i = 0;
@@ -1208,6 +1251,10 @@ static void __camera_task_process_job(muse_camera_handle_s *muse_camera, muse_ca
        case MUSE_CAMERA_API_UNSET_EXTRA_PREVIEW_CB:
                ret = __camera_dispatcher_unset_preview_cb_flag(muse_camera, PREVIEW_CB_TYPE_EXTRA);
                break;
+       case MUSE_CAMERA_API_FORCE_STOP:
+               ret = __camera_force_stop(muse_camera);
+               legacy_camera_send_signal(muse_camera->camera_handle);
+               goto _PROCESS_DONE;
        default:
                CAM_LOG_ERROR("unhandled task - api[%d]", job->api);
                goto _PROCESS_DONE;
@@ -6367,10 +6414,10 @@ int (*dispatcher[MUSE_CAMERA_API_MAX]) (muse_module_h module) = {
 static int camera_cmd_dispatcher_shutdown(muse_module_h module)
 {
        muse_camera_handle_s *muse_camera = NULL;
-       camera_state_e state = CAMERA_STATE_NONE;
-       int capture_try_count = 0;
        int ret = 0;
 
+       CAM_LOG_WARNING("enter");
+
        muse_camera = (muse_camera_handle_s *)muse_server_ipc_get_handle(module);
        if (muse_camera == NULL) {
                CAM_LOG_ERROR("NULL handle");
@@ -6381,7 +6428,7 @@ static int camera_cmd_dispatcher_shutdown(muse_module_h module)
 
        if (legacy_camera_is_used(muse_camera->camera_handle)) {
                CAM_LOG_WARNING("camera is used in recorder.. wait...");
-               if (legacy_camera_wait(muse_camera->camera_handle, 3000)) {
+               if (legacy_camera_wait(muse_camera->camera_handle, MUSED_CAMERA_WAIT_TIME_IN_USED)) {
                        CAM_LOG_INFO("recorder is released");
                } else {
                        legacy_camera_lock(muse_camera->camera_handle, false);
@@ -6390,46 +6437,29 @@ static int camera_cmd_dispatcher_shutdown(muse_module_h module)
                }
        }
 
-       legacy_camera_lock(muse_camera->camera_handle, false);
-
        muse_camera->is_module_available = false;
 
-again:
-       legacy_camera_get_state(muse_camera->camera_handle, &state);
+       _camera_task_add_job(muse_camera,
+               MUSE_CAMERA_API_FORCE_STOP,
+               MUSE_CAMERA_API_CLASS_IMMEDIATE,
+               0);
 
-       CAM_LOG_WARNING("current state[%d]", state);
+       CAM_LOG_WARNING("FORCE_STOP task added and wait for signal");
 
-       switch (state) {
-       case CAMERA_STATE_CAPTURING:
-               if (capture_try_count < 30) {
-                       CAM_LOG_WARNING("now capturing.. wait for capture data...");
-                       usleep(100 * 1000);
-                       capture_try_count++;
-                       goto again;
-               } else {
-                       CAM_LOG_ERROR("wait capture data timeout! keep going...");
-               }
-               /* fall through */
-       case CAMERA_STATE_CAPTURED:
-               legacy_camera_start_preview(muse_camera->camera_handle);
-               /* fall through */
-       case CAMERA_STATE_PREVIEW:
-               camera_remove_export_data(&muse_camera->camera_data, -1); /* force return buffer before stop preview */
-               legacy_camera_stop_preview(muse_camera->camera_handle);
-               /* fall through */
-       case CAMERA_STATE_CREATED:
-               ret = legacy_camera_destroy(muse_camera->camera_handle);
-               if (ret == CAMERA_ERROR_NONE)
-                       _camera_dispatcher_release_resource(module);
-               else
-                       CAM_LOG_ERROR("failed to destroy camera handle");
+       if (legacy_camera_wait(muse_camera->camera_handle, MUSED_CAMERA_WAIT_TIME_FORCE_STOP))
+               CAM_LOG_WARNING("camera stop done");
+       else
+               CAM_LOG_ERROR("camera stop failed[handle:%p]", muse_camera->camera_handle);
 
-               break;
-       default:
-               break;
-       }
+       legacy_camera_lock(muse_camera->camera_handle, false);
+
+       ret = legacy_camera_destroy(muse_camera->camera_handle);
+       if (ret == CAMERA_ERROR_NONE)
+               _camera_dispatcher_release_resource(module);
+       else
+               CAM_LOG_ERROR("failed to destroy camera handle[0x%x]", ret);
 
-       CAM_LOG_WARNING("done");
+       CAM_LOG_WARNING("leave");
 
        return MUSE_CAMERA_ERROR_NONE;
 }
index 028d9a5..70e55ff 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mmsvc-camera
 Summary:    A Camera module for muse server
-Version:    0.3.59
+Version:    0.3.60
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0