New APIs are added 52/87552/9
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 8 Sep 2016 12:48:29 +0000 (21:48 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Tue, 13 Sep 2016 08:41:56 +0000 (17:41 +0900)
New enum :
camera_device_state_e
New function :
camera_get_device_state
camera_add_device_state_changed_cb
camera_remove_device_state_changed_cb

[Version] 0.2.73
[Profile] Common
[Issue Type] New function
[Dependency module] N/A
[Dependency commit] N/A
[Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-mobile_20160907.3]

Change-Id: I9395c0b56c5dc3ebe738776f5ad91d5eca829733
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
CMakeLists.txt
include/camera.h
include/camera_private.h
packaging/capi-media-camera.spec
src/camera.c
test/camera_test.c

index a8d9ab0..e334558 100644 (file)
@@ -10,9 +10,9 @@ SET(submodule "camera")
 
 # for package file
 IF(TIZEN_FEATURE_EVAS_RENDERER)
-SET(dependents "libtbm dlog mm-common capi-base-common capi-media-tool ecore elementary mmsvc-camera tizen-extension-client mm-evas-renderer")
+SET(dependents "glib-2.0 gio-2.0 libtbm dlog mm-common capi-base-common capi-media-tool ecore elementary mmsvc-camera tizen-extension-client mm-evas-renderer")
 ELSE(TIZEN_FEATURE_EVAS_RENDERER)
-SET(dependents "libtbm dlog mm-common capi-base-common capi-media-tool ecore elementary mmsvc-camera tizen-extension-client")
+SET(dependents "glib-2.0 gio-2.0 libtbm dlog mm-common capi-base-common capi-media-tool ecore elementary mmsvc-camera tizen-extension-client")
 ENDIF(TIZEN_FEATURE_EVAS_RENDERER)
 SET(pc_dependents "capi-base-common capi-media-tool libtbm evas ecore elementary")
 SET(fw_name "${project_prefix}-${service}-${submodule}")
index e394ca1..9c17aa3 100644 (file)
@@ -74,6 +74,16 @@ typedef enum {
 } camera_state_e;
 
 /**
+ * @brief Enumeration for the camera device state.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       CAMERA_DEVICE_STATE_NULL,       /**< Not opened */
+       CAMERA_DEVICE_STATE_OPENED,     /**< Opened */
+       CAMERA_DEVICE_STATE_WORKING     /**< Now previewing or capturing or is being used for video recording */
+} camera_device_state_e;
+
+/**
  * @brief Enumeration for the camera device.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  */
@@ -516,7 +526,6 @@ typedef enum {
 /**
  * @brief Called when the camera state is changed.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- *
  * @param[in] previous The previous state of the camera
  * @param[in] current The current state of the camera
  * @param[in] by_policy If @c true the state is changed by policy, otherwise @c false
@@ -528,9 +537,18 @@ typedef enum {
 typedef void (*camera_state_changed_cb)(camera_state_e previous, camera_state_e current, bool by_policy, void *user_data);
 
 /**
+ * @brief Called when the camera device state is changed.
+ * @since_tizen 3.0
+ * @param[in] device The hardware camera type
+ * @param[in] state The state of the camera device
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see        camera_add_device_state_changed_cb()
+ */
+typedef void (*camera_device_state_changed_cb)(camera_device_e device, camera_device_state_e state, void *user_data);
+
+/**
  * @brief Called when the camera is interrupted by policy.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- *
  * @param[in] policy The policy that interrupted the camera
  * @param[in] previous The previous state of the camera
  * @param[in] current The current state of the camera
@@ -595,7 +613,7 @@ typedef void (*camera_media_packet_preview_cb)(media_packet_h pkt, void *user_da
  * @brief Called to get information about image data taken by the camera once per frame while capturing.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  *
- * @remarks This function is issued in the context of gstreamer (video source thread) so the UI update code should not be directly invoked.
+ * @remarks This function is issued in the context of internal framework so the UI update code should not be directly invoked.
  *          You must not call camera_start_preview() within this callback.
  *
  * @param[in] image The image data of the captured picture
@@ -614,8 +632,8 @@ typedef void (*camera_capturing_cb)(camera_image_data_s *image, camera_image_dat
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  *
  * @remarks The callback is called after camera_capturing_cb() is completed.\n
- *          If you want to show the user a preview after capturing is finished, an application can use camera_start_preview() after calling this callback.
- *
+ *          If you want to show the user a preview after capturing is finished, \n
+ *          an application can use camera_start_preview() after calling this callback.
  * @param[in] user_data The user data passed from the callback registration function
  * @pre        This callback function is invoked if it is registered using camera_start_capture() or camera_start_continuous_capture().
  * @see        camera_start_capture()
@@ -633,8 +651,7 @@ typedef void (*camera_capture_completed_cb)(void *user_data);
  *          In case of errors, one of these codes occur:\n
  * #CAMERA_ERROR_DEVICE,\n
  * #CAMERA_ERROR_INVALID_OPERATION,\n
- * #CAMERA_ERROR_OUT_OF_MEMORY.\n
- *
+ * #CAMERA_ERROR_OUT_OF_MEMORY.
  * @param[in] error The error code
  * @param[in] current_state The current state of the camera
  * @param[in] user_data        The user data passed from the callback registration function
@@ -1932,6 +1949,50 @@ int camera_set_error_cb(camera_h camera, camera_error_cb callback, void *user_da
 int camera_unset_error_cb(camera_h camera);
 
 /**
+ * @brief Gets the state of camera device.
+ * @since_tizen 3.0
+ * @param[in] device The hardware camera type
+ * @param[out] state The current state of the device
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #CAMERA_ERROR_NONE Successful
+ * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #CAMERA_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #CAMERA_ERROR_NOT_SUPPORTED The feature is not supported
+ */
+int camera_get_device_state(camera_device_e device, camera_device_state_e *state);
+
+/**
+ * @brief Registers a callback function to be called when the camera device state changes.
+ * @since_tizen 3.0
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] cb_id The id of registerd callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #CAMERA_ERROR_NONE Successful
+ * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #CAMERA_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #CAMERA_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #CAMERA_ERROR_NOT_SUPPORTED The feature is not supported
+ * @post This function will invoke camera_device_state_changed_cb() when the camera device's state changes.
+ * @see camera_remove_device_state_changed_cb()
+ * @see camera_device_state_changed_cb()
+ */
+int camera_add_device_state_changed_cb(camera_device_state_changed_cb callback, void *user_data, int *cb_id);
+
+/**
+ * @brief Unregisters the callback function.
+ * @since_tizen 3.0
+ * @param[in] cb_id The id of registerd callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #CAMERA_ERROR_NONE Successful
+ * @retval #CAMERA_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #CAMERA_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #CAMERA_ERROR_NOT_SUPPORTED The feature is not supported
+ * @see camera_add_device_state_changed_cb()
+ */
+int camera_remove_device_state_changed_cb(int cb_id);
+
+/**
  * @}
  */
 
index 49a9571..8d84f75 100644 (file)
@@ -19,7 +19,8 @@
 
 
 #ifndef __TIZEN_MULTIMEDIA_CAMERA_PRIVATE_H__
-#define        __TIZEN_MULTIMEDIA_CAMERA_PRIVATE_H__
+#define __TIZEN_MULTIMEDIA_CAMERA_PRIVATE_H__
+#include <glib.h>
 #include <camera.h>
 #include <muse_core.h>
 #include <muse_camera.h>
@@ -105,12 +106,18 @@ typedef struct _camera_msg_handler_info_s {
 } camera_msg_handler_info_s;
 
 typedef struct _camera_cb_info_s {
+       /* server connection */
        gint fd;
        gboolean is_server_connected;
 
        /* message receive thread */
        GThread *msg_recv_thread;
        gint msg_recv_running;
+       gchar recv_msg[MUSE_CAMERA_MSG_MAX_LENGTH];
+       GCond api_cond[MUSE_CAMERA_API_MAX];
+       GMutex api_mutex[MUSE_CAMERA_API_MAX];
+       gint api_activating[MUSE_CAMERA_API_MAX];
+       gint api_ret[MUSE_CAMERA_API_MAX];
 
        /* general message handler info */
        camera_msg_handler_info_s msg_handler_info;
@@ -121,20 +128,26 @@ typedef struct _camera_cb_info_s {
        /* capture cb message handler info */
        camera_msg_handler_info_s capture_cb_info;
 
+       /* idle event */
        GList *idle_event_list;
        GCond idle_event_cond;
        GMutex idle_event_mutex;
+
+       /* user callback */
        gpointer user_cb[MUSE_CAMERA_EVENT_TYPE_NUM];
        gpointer user_data[MUSE_CAMERA_EVENT_TYPE_NUM];
-       gchar recv_msg[MUSE_CAMERA_MSG_MAX_LENGTH];
-       GCond api_cond[MUSE_CAMERA_API_MAX];
-       GMutex api_mutex[MUSE_CAMERA_API_MAX];
-       gint api_activating[MUSE_CAMERA_API_MAX];
-       gint api_ret[MUSE_CAMERA_API_MAX];
+
+       /* tbm */
        tbm_bufmgr bufmgr;
+
+       /* media packet */
        media_format_h pkt_fmt;
-       int preview_cb_flag;
        GMutex mp_data_mutex;
+
+       /* preview callback flag */
+       int preview_cb_flag;
+
+       /* evas surface */
 #ifdef TIZEN_FEATURE_EVAS_RENDERER
        void *evas_info;
        GMutex evas_mutex;
@@ -190,12 +203,19 @@ typedef struct _camera_msg_param {
        } value;
 } camera_msg_param;
 
+typedef struct _camera_cb_info {
+       int id;
+       void *callback;
+       void *user_data;
+} camera_cb_info;
+
 
 int _camera_get_tbm_surface_format(int in_format, uint32_t *out_format);
 int _camera_get_media_packet_mimetype(int in_format, media_format_mimetype_e *mimetype);
 int _camera_media_packet_finalize(media_packet_h pkt, int error_code, void *user_data);
 int _camera_start_evas_rendering(camera_h camera);
 int _camera_stop_evas_rendering(camera_h camera, bool keep_screen);
+int _camera_independent_request(int api, int device_type, const char *key, int *value);
 
 typedef bool (*camera_supported_cb_param1)(int param, void *user_data);
 typedef bool (*camera_supported_cb_param2)(int param1, int param2, void *user_data);
index c69fa5d..5a8a3a9 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-camera
 Summary:    A Camera API
-Version:    0.2.72
+Version:    0.2.73
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
@@ -8,6 +8,7 @@ Source0:    %{name}-%{version}.tar.gz
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(mused)
 BuildRequires:  pkgconfig(mm-common)
 BuildRequires:  pkgconfig(capi-base-common)
index b71ac92..78bf839 100644 (file)
 #ifdef TIZEN_FEATURE_EVAS_RENDERER
 #include <mm_evas_renderer.h>
 #endif /* TIZEN_FEATURE_EVAS_RENDERER */
+#include <gio/gio.h>
 
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 #define LOG_TAG "TIZEN_N_CAMERA"
 
+/* for device changed callback */
+static GMutex g_cam_dev_state_changed_cb_lock;
+static GList *g_cam_dev_state_changed_cb_list;
+static int g_cam_dev_state_changed_cb_id;
+static GDBusConnection *g_cam_dev_state_changed_cb_conn;
+static guint g_cam_dev_state_changed_cb_subscribe_id;
 
 static void __global(void *data, struct wl_registry *registry,
        uint32_t name, const char *interface, uint32_t version)
@@ -227,6 +234,56 @@ _DONE:
 }
 
 
+static void __camera_device_state_changed_cb(GDBusConnection *connection,
+       const gchar *sender_name, const gchar *object_path, const gchar *interface_name,
+       const gchar *signal_name, GVariant *param, gpointer user_data)
+{
+       int value = 0;
+       camera_device_e device = CAMERA_DEVICE_CAMERA0;
+       camera_device_state_e state = CAMERA_DEVICE_STATE_NULL;
+       GList *tmp_list = NULL;
+       camera_cb_info *info = NULL;
+
+       g_mutex_lock(&g_cam_dev_state_changed_cb_lock);
+
+       if (!g_cam_dev_state_changed_cb_list || !param) {
+               LOGW("no callback or NULL param %p", param);
+               goto _DONE;
+       }
+
+       /* get device and state */
+       g_variant_get(param, "(i)", &value);
+
+       device = value >> 16;
+       state = 0x0000ffff & value;
+
+       LOGD("device %d, state %d", device, state);
+
+       tmp_list = g_cam_dev_state_changed_cb_list;
+
+       do {
+               info = (camera_cb_info *)tmp_list->data;
+
+               if (info) {
+                       if (info->callback) {
+                               LOGD("start id[%d] callback", info->id);
+                               ((camera_device_state_changed_cb)info->callback)(device, state, info->user_data);
+                               LOGD("returned id[%d] callback", info->id);
+                       } else {
+                               LOGW("NULL callback for id %d", info->id);
+                       }
+               }
+
+               tmp_list = tmp_list->next;
+       } while (tmp_list);
+
+_DONE:
+       g_mutex_unlock(&g_cam_dev_state_changed_cb_lock);
+
+       return;
+}
+
+
 static int _camera_import_tbm_key(tbm_bufmgr bufmgr, unsigned int tbm_key, tbm_bo *bo, tbm_bo_handle *bo_handle)
 {
        tbm_bo tmp_bo = NULL;
@@ -1476,7 +1533,7 @@ static void *_camera_msg_handler_func(gpointer data)
        camera_cb_info_s *cb_info = NULL;
 
        if (!handler_info || !handler_info->cb_info) {
-               LOGE("t:%d NULL handler %p", type, handler_info);
+               LOGE("NULL handler %p", handler_info);
                return NULL;
        }
 
@@ -1545,7 +1602,7 @@ static void *_camera_msg_handler_func(gpointer data)
                                g_mutex_init(&cam_idle_event->event_mutex);
                                strncpy(cam_idle_event->recv_msg, cam_msg->recv_msg, sizeof(cam_idle_event->recv_msg) - 1);
 
-                               /*LOGD("t:%d add camera event[%d, %p] to IDLE", type, event, cam_idle_event);*/
+                               /*LOGD("t:%d add camera event[%d, %p] to IDLE", type, cam_msg->event, cam_idle_event);*/
 
                                g_mutex_lock(&cb_info->idle_event_mutex);
                                cb_info->idle_event_list = g_list_append(cb_info->idle_event_list, (gpointer)cam_idle_event);
@@ -1837,9 +1894,10 @@ static void *_camera_msg_recv_func(gpointer data)
                                                g_atomic_int_set(&cb_info->msg_recv_running, 0);
                                                LOGD("camera destroy done. close client cb handler");
                                        }
-                               } else if (api == MUSE_CAMERA_API_GET_FLASH_STATE) {
+                               } else if (api == MUSE_CAMERA_API_GET_FLASH_STATE ||
+                                       api == MUSE_CAMERA_API_GET_DEVICE_STATE) {
                                        g_atomic_int_set(&cb_info->msg_recv_running, 0);
-                                       LOGD("get flash state done. close client cb handler");
+                                       LOGD("get flash or device state done. close client cb handler");
                                }
 
                                g_cond_signal(&cb_info->api_cond[api]);
@@ -2200,6 +2258,91 @@ int _camera_stop_evas_rendering(camera_h camera, bool keep_screen)
 }
 
 
+int _camera_independent_request(int api, int device_type, const char *key, int *value)
+{
+       int ret = CAMERA_ERROR_NONE;
+       int send_ret = 0;
+       int sock_fd = -1;
+       char *msg = NULL;
+       camera_cli_s *pc = NULL;
+
+       /* create muse connection */
+       if (!key || !value) {
+               LOGE("NULL pointer");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       sock_fd = muse_core_client_new();
+       if (sock_fd < 0) {
+               LOGE("muse_core_client_new failed");
+               return CAMERA_ERROR_INVALID_OPERATION;
+       }
+
+       msg = muse_core_msg_json_factory_new(api,
+               MUSE_TYPE_INT, "module", MUSE_CAMERA,
+               MUSE_TYPE_INT, PARAM_DEVICE_TYPE, device_type,
+               0);
+       if (!msg) {
+               LOGE("msg failed");
+               ret = CAMERA_ERROR_OUT_OF_MEMORY;
+               goto _REQUEST_EXIT;
+       }
+
+       send_ret = muse_core_ipc_send_msg(sock_fd, msg);
+
+       muse_core_msg_json_factory_free(msg);
+       msg = NULL;
+
+       if (send_ret < 0) {
+               LOGE("send msg failed");
+               ret = CAMERA_ERROR_INVALID_OPERATION;
+               goto _REQUEST_EXIT;
+       }
+
+       pc = g_new0(camera_cli_s, 1);
+       if (!pc) {
+               LOGE("handle alloc failed");
+               ret = CAMERA_ERROR_OUT_OF_MEMORY;
+               goto _REQUEST_EXIT;
+       }
+
+       pc->cb_info = _camera_client_callback_new(sock_fd, false);
+       if (!pc->cb_info) {
+               LOGE("cb_info alloc failed");
+               ret = CAMERA_ERROR_OUT_OF_MEMORY;
+               goto _REQUEST_EXIT;
+       }
+
+       sock_fd = -1;
+
+       ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT);
+
+       if (ret == CAMERA_ERROR_NONE)
+               muse_core_msg_json_deserialize(key, pc->cb_info->recv_msg, NULL, value, NULL, MUSE_TYPE_ANY);
+
+       LOGD("api %d - value %d", api, *value);
+
+_REQUEST_EXIT:
+       /* release resources */
+       if (pc) {
+               if (pc->cb_info) {
+                       _camera_client_callback_destroy(pc->cb_info);
+                       pc->cb_info = NULL;
+               }
+
+               g_free(pc);
+               pc = NULL;
+       }
+
+       if (sock_fd > -1) {
+               muse_core_connection_close(sock_fd);
+               sock_fd = -1;
+       }
+
+       return ret;
+}
+
+
 int camera_create(camera_device_e device, camera_h *camera)
 {
        int sock_fd = -1;
@@ -2492,8 +2635,10 @@ bool camera_is_supported_continuous_capture(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -2567,8 +2712,10 @@ bool camera_is_supported_face_detection(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -2591,8 +2738,10 @@ bool camera_is_supported_zero_shutter_lag(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -2615,8 +2764,10 @@ bool camera_is_supported_media_packet_preview_cb(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -3468,13 +3619,14 @@ int camera_set_preview_cb(camera_h camera, camera_preview_cb callback, void *use
 
        LOGD("Enter");
 
-       pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = callback;
-       pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = user_data;
-
-       SET_PREVIEW_CB_TYPE(pc->cb_info, PREVIEW_CB_TYPE_USER);
-
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
+       if (ret == CAMERA_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = callback;
+               pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_PREVIEW] = user_data;
+               SET_PREVIEW_CB_TYPE(pc->cb_info, PREVIEW_CB_TYPE_USER);
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -3530,11 +3682,13 @@ int camera_set_media_packet_preview_cb(camera_h camera, camera_media_packet_prev
 
        LOGD("Enter");
 
-       pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW] = callback;
-       pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW] = user_data;
-
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
+       if (ret == CAMERA_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW] = callback;
+               pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_MEDIA_PACKET_PREVIEW] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -3578,11 +3732,13 @@ int camera_set_state_changed_cb(camera_h camera, camera_state_changed_cb callbac
 
        LOGD("Enter");
 
-       pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_STATE_CHANGE] = callback;
-       pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_STATE_CHANGE] = user_data;
-
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
+       if (ret == CAMERA_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_STATE_CHANGE] = callback;
+               pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_STATE_CHANGE] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -3626,11 +3782,13 @@ int camera_set_interrupted_cb(camera_h camera, camera_interrupted_cb callback, v
 
        LOGD("Enter");
 
-       pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_INTERRUPTED] = callback;
-       pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_INTERRUPTED] = user_data;
-
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
+       if (ret == CAMERA_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_INTERRUPTED] = callback;
+               pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_INTERRUPTED] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -3674,11 +3832,13 @@ int camera_set_focus_changed_cb(camera_h camera, camera_focus_changed_cb callbac
 
        LOGD("Enter");
 
-       pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FOCUS_CHANGE] = callback;
-       pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_FOCUS_CHANGE] = user_data;
-
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
+       if (ret == CAMERA_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_FOCUS_CHANGE] = callback;
+               pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_FOCUS_CHANGE] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -3722,11 +3882,13 @@ int camera_set_error_cb(camera_h camera, camera_error_cb callback, void *user_da
 
        LOGD("Enter");
 
-       pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_ERROR] = callback;
-       pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_ERROR] = user_data;
-
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
+       if (ret == CAMERA_ERROR_NONE) {
+               pc->cb_info->user_cb[MUSE_CAMERA_EVENT_TYPE_ERROR] = callback;
+               pc->cb_info->user_data[MUSE_CAMERA_EVENT_TYPE_ERROR] = user_data;
+       }
+
        LOGD("ret : 0x%x", ret);
 
        return ret;
@@ -5229,90 +5391,22 @@ int camera_attr_get_flash_mode(camera_h camera, camera_attr_flash_mode_e *mode)
 
 int camera_get_flash_state(camera_device_e device, camera_flash_state_e *state)
 {
-       int sock_fd = -1;
-       char *msg = NULL;
        int ret = CAMERA_ERROR_NONE;
-       int send_ret = 0;
-       camera_cli_s *pc = NULL;
        int get_flash_state = 0;
 
-       /* create muse connection */
-       muse_camera_api_e api = MUSE_CAMERA_API_GET_FLASH_STATE;
-       muse_core_api_module_e muse_module = MUSE_CAMERA;
-       int device_type = (int)device;
-
        if (!state) {
                LOGE("NULL pointer");
                return CAMERA_ERROR_INVALID_PARAMETER;
        }
 
-       sock_fd = muse_core_client_new();
-       if (sock_fd < 0) {
-               LOGE("muse_core_client_new failed");
-               return CAMERA_ERROR_INVALID_OPERATION;
-       }
-
-       msg = muse_core_msg_json_factory_new(api,
-               MUSE_TYPE_INT, "module", muse_module,
-               MUSE_TYPE_INT, PARAM_DEVICE_TYPE, device_type,
-               0);
-       if (!msg) {
-               LOGE("msg failed");
-               ret = CAMERA_ERROR_OUT_OF_MEMORY;
-               goto Exit;
-       }
-
-       send_ret = muse_core_ipc_send_msg(sock_fd, msg);
-
-       muse_core_msg_json_factory_free(msg);
-       msg = NULL;
-
-       if (send_ret < 0) {
-               LOGE("send msg failed");
-               ret = CAMERA_ERROR_INVALID_OPERATION;
-               goto Exit;
-       }
-
-       pc = g_new0(camera_cli_s, 1);
-       if (!pc) {
-               LOGE("handle alloc failed");
-               ret = CAMERA_ERROR_OUT_OF_MEMORY;
-               goto Exit;
-       }
-
-       pc->cb_info = _camera_client_callback_new(sock_fd, false);
-       if (!pc->cb_info) {
-               LOGE("cb_info alloc failed");
-               ret = CAMERA_ERROR_OUT_OF_MEMORY;
-               goto Exit;
-       }
-
-       sock_fd = -1;
-
-       ret = _camera_client_wait_for_cb_return(api, pc->cb_info, CAMERA_CB_TIMEOUT);
+       ret = _camera_independent_request(MUSE_CAMERA_API_GET_FLASH_STATE,
+               (int)device, "get_flash_state", &get_flash_state);
 
        if (ret == CAMERA_ERROR_NONE) {
-               muse_camera_msg_get(get_flash_state, pc->cb_info->recv_msg);
                *state = (camera_flash_state_e)get_flash_state;
-       }
-
-       LOGD("Flash state : %d", *state);
-
-Exit:
-       /* release resources */
-       if (pc) {
-               if (pc->cb_info) {
-                       _camera_client_callback_destroy(pc->cb_info);
-                       pc->cb_info = NULL;
-               }
-
-               g_free(pc);
-               pc = NULL;
-       }
-
-       if (sock_fd > -1) {
-               muse_core_connection_close(sock_fd);
-               sock_fd = -1;
+               LOGD("flash state %d", *state);
+       } else {
+               LOGE("failed 0x%x", ret);
        }
 
        return ret;
@@ -5758,8 +5852,10 @@ bool camera_attr_is_supported_hdr_capture(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -5892,8 +5988,10 @@ bool camera_attr_is_supported_anti_shake(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -5968,8 +6066,10 @@ bool camera_attr_is_supported_video_stabilization(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -6044,8 +6144,10 @@ bool camera_attr_is_supported_auto_contrast(camera_h camera)
 
        _camera_msg_send(api, pc->cb_info, &ret, CAMERA_CB_TIMEOUT);
 
-       if (ret == CAMERA_ERROR_SERVICE_DISCONNECTED)
+       if (ret < 0) {
+               LOGE("error is occurred 0x%x", ret);
                ret = false;
+       }
 
        LOGD("ret : %d", ret);
 
@@ -6384,3 +6486,177 @@ int camera_attr_get_display_roi_area(camera_h camera, int *x, int *y, int *width
 
        return ret;
 }
+
+
+int camera_get_device_state(camera_device_e device, camera_device_state_e *state)
+{
+       int ret = CAMERA_ERROR_NONE;
+       int get_device_state = 0;
+
+       if (!state) {
+               LOGE("NULL pointer");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = _camera_independent_request(MUSE_CAMERA_API_GET_DEVICE_STATE,
+               (int)device, "get_device_state", &get_device_state);
+
+       if (ret == CAMERA_ERROR_NONE) {
+               *state = (camera_device_state_e)get_device_state;
+               LOGD("device state %d", *state);
+       } else {
+               LOGE("failed 0x%x", ret);
+       }
+
+       return ret;
+}
+
+
+int camera_add_device_state_changed_cb(camera_device_state_changed_cb callback, void *user_data, int *cb_id)
+{
+       int ret = CAMERA_ERROR_NONE;
+       camera_device_state_e state = CAMERA_DEVICE_STATE_NULL;
+       camera_cb_info *info = NULL;
+
+       if (!callback || !cb_id) {
+               LOGE("invalid pointer %p %p", callback, cb_id);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check camera support */
+       ret = camera_get_device_state(CAMERA_DEVICE_CAMERA0, &state);
+       if (ret != CAMERA_ERROR_NONE) {
+               LOGE("get device state failed");
+               return ret;
+       }
+
+       g_mutex_lock(&g_cam_dev_state_changed_cb_lock);
+
+       info = g_new0(camera_cb_info, 1);
+       if (!info) {
+               LOGE("info failed");
+               ret = CAMERA_ERROR_OUT_OF_MEMORY;
+               goto _DONE;
+       }
+
+       info->id = ++g_cam_dev_state_changed_cb_id;
+       info->callback = (void *)callback;
+
+       *cb_id = info->id;
+
+       /* subscribe dbus signal for camera state change */
+       if (!g_cam_dev_state_changed_cb_conn) {
+               g_cam_dev_state_changed_cb_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+               if (!g_cam_dev_state_changed_cb_conn) {
+                       LOGE("failed to get gdbus connection");
+                       ret = CAMERA_ERROR_INVALID_OPERATION;
+                       goto _DONE;
+               }
+
+               LOGD("subscribe signal %s - %s - %s",
+                       MM_CAMCORDER_DBUS_OBJECT,
+                       MM_CAMCORDER_DBUS_INTERFACE_CAMERA,
+                       MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED);
+
+               g_cam_dev_state_changed_cb_subscribe_id = g_dbus_connection_signal_subscribe(g_cam_dev_state_changed_cb_conn,
+                       NULL, MM_CAMCORDER_DBUS_INTERFACE_CAMERA, MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED, MM_CAMCORDER_DBUS_OBJECT, NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)__camera_device_state_changed_cb, NULL, NULL);
+               if (!g_cam_dev_state_changed_cb_subscribe_id) {
+                       LOGE("failed to get gdbus connection");
+                       ret = CAMERA_ERROR_INVALID_OPERATION;
+                       goto _DONE;
+               }
+
+               LOGD("signal subscribe id %u", g_cam_dev_state_changed_cb_subscribe_id);
+       }
+
+       g_cam_dev_state_changed_cb_list = g_list_prepend(g_cam_dev_state_changed_cb_list, (gpointer)info);
+
+       LOGD("callback id %d", info->id);
+
+_DONE:
+       if (ret != CAMERA_ERROR_NONE) {
+               if (info) {
+                       g_free(info);
+                       info = NULL;
+               }
+
+               if (g_cam_dev_state_changed_cb_conn) {
+                       g_object_unref(g_cam_dev_state_changed_cb_conn);
+                       g_cam_dev_state_changed_cb_conn = NULL;
+               }
+       }
+
+       g_mutex_unlock(&g_cam_dev_state_changed_cb_lock);
+
+       return ret;
+}
+
+
+int camera_remove_device_state_changed_cb(int cb_id)
+{
+       int ret = CAMERA_ERROR_NONE;
+       camera_device_state_e state = CAMERA_DEVICE_STATE_NULL;
+       GList *tmp_list = NULL;
+       camera_cb_info *info = NULL;
+
+       /* check camera support */
+       ret = camera_get_device_state(CAMERA_DEVICE_CAMERA0, &state);
+       if (ret != CAMERA_ERROR_NONE) {
+               LOGE("get device state failed");
+               return ret;
+       }
+
+       g_mutex_lock(&g_cam_dev_state_changed_cb_lock);
+
+       if (!g_cam_dev_state_changed_cb_list) {
+               LOGE("there is no callback info");
+               ret = CAMERA_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       tmp_list = g_cam_dev_state_changed_cb_list;
+
+       do {
+               info = tmp_list->data;
+               tmp_list = tmp_list->next;
+
+               if (!info) {
+                       LOGW("NULL info");
+                       continue;
+               }
+
+               if (info->id == cb_id) {
+                       g_cam_dev_state_changed_cb_list = g_list_remove(g_cam_dev_state_changed_cb_list, info);
+
+                       g_free(info);
+                       info = NULL;
+
+                       if (!g_cam_dev_state_changed_cb_list) {
+                               /* no remained callback */
+                               if (g_cam_dev_state_changed_cb_conn) {
+                                       /* unsubscribe signal */
+                                       g_dbus_connection_signal_unsubscribe(g_cam_dev_state_changed_cb_conn, g_cam_dev_state_changed_cb_subscribe_id);
+                                       g_cam_dev_state_changed_cb_subscribe_id = 0;
+
+                                       /* unref connection */
+                                       g_object_unref(g_cam_dev_state_changed_cb_conn);
+                                       g_cam_dev_state_changed_cb_conn = NULL;
+                               }
+                       }
+
+                       LOGD("id %d callback removed", cb_id);
+                       ret = CAMERA_ERROR_NONE;
+
+                       goto _DONE;
+               }
+       } while (tmp_list);
+
+       LOGE("id %d callback not found", cb_id);
+       ret = CAMERA_ERROR_INVALID_PARAMETER;
+
+_DONE:
+       g_mutex_unlock(&g_cam_dev_state_changed_cb_lock);
+
+       return ret;
+}
index 962db77..1d3b608 100644 (file)
@@ -70,6 +70,7 @@ int camera_state;
 int camera_print_state;
 int multishot_num;
 static GTimer *timer = NULL;
+static int g_camera_device_changed_cb_id;
 
 GTimeVal previous_time;
 GTimeVal current_time;
@@ -130,7 +131,7 @@ GTimeVal res;
                int ret = 0; \
                ret = expr; \
                if (ret != 0) {\
-                       printf("[%s:%d] error code : %x \n", __func__, __LINE__, ret); \
+                       g_print("[%s:%d] error code : %x \n", __func__, __LINE__, ret); \
                        return; \
                } \
        } while (0)
@@ -435,7 +436,7 @@ static inline void flush_stdin()
 
 static bool _release_idle_event_callback(void *data)
 {
-       printf("destroy camera handle\n\n");
+       g_print("destroy camera handle\n\n");
 
        camera_destroy(hcamcorder->camera);
        hcamcorder->camera = NULL;
@@ -447,17 +448,17 @@ static bool _release_idle_event_callback(void *data)
 
 static void _camera_error_cb(int error, camera_state_e current_state, void *user_data)
 {
-       printf("\n\n\tERROR [0x%x], current state %d\n", error, current_state);
+       g_print("\n\n\tERROR [0x%x], current state %d\n", error, current_state);
 
        switch (error) {
        case CAMERA_ERROR_RESOURCE_CONFLICT:
-               printf("\t\t[CAMERA_ERROR_RESOURCE_CONFLICT]\n\n");
+               g_print("\t\t[CAMERA_ERROR_RESOURCE_CONFLICT]\n\n");
                break;
        case CAMERA_ERROR_SECURITY_RESTRICTED:
-               printf("\t\t[CAMERA_ERROR_SECURITY_RESTRICTED]\n\n");
+               g_print("\t\t[CAMERA_ERROR_SECURITY_RESTRICTED]\n\n");
                break;
        case CAMERA_ERROR_SERVICE_DISCONNECTED:
-               printf("\t\t[CAMERA_ERROR_SERVICE_DISCONNECTED]\n\n");
+               g_print("\t\t[CAMERA_ERROR_SERVICE_DISCONNECTED]\n\n");
                g_idle_add_full(G_PRIORITY_DEFAULT,
                        (GSourceFunc)_release_idle_event_callback,
                        NULL, NULL);
@@ -471,12 +472,20 @@ static void _camera_error_cb(int error, camera_state_e current_state, void *user
 
 static void _camera_state_changed_cb(camera_state_e previous, camera_state_e current, bool by_policy, void *user_data)
 {
-       printf("camera state changed %d -> %d\n", previous, current);
+       g_print("\ncamera state changed %d -> %d\n", previous, current);
+       return;
+}
+
+static void _camera_device_state_changed_cb(camera_device_e device, camera_device_state_e state, void *user_data)
+{
+       g_print("\ncamera device[%d] state changed to %d\n", device, state);
+       return;
 }
 
 static void _camera_interrupted_cb(camera_policy_e policy, camera_state_e previous, camera_state_e current, void *user_data)
 {
-       printf("camera interrupted callback called %d\n", policy);
+       g_print("\ncamera interrupted callback called %d\n", policy);
+       return;
 }
 
 static bool preview_resolution_cb(int width, int height, void *user_data)
@@ -484,14 +493,14 @@ static bool preview_resolution_cb(int width, int height, void *user_data)
        resolution_stack *data = (resolution_stack *)user_data;
 
        if (data == NULL) {
-               printf("NULL data\n");
+               g_print("NULL data\n");
                return false;
        }
 
        data->width[data->count] = width;
        data->height[data->count] = height;
 
-       printf("%d. %dx%d\n", data->count, width, height);
+       g_print("%d. %dx%d\n", data->count, width, height);
 
        data->count++;
 
@@ -503,14 +512,14 @@ static bool capture_resolution_test_cb(int width, int height, void *user_data)
        resolution_stack *data = (resolution_stack *)user_data;
 
        if (data == NULL) {
-               printf("NULL data\n");
+               g_print("NULL data\n");
                return false;
        }
 
        data->width[data->count] = width;
        data->height[data->count] = height;
 
-       printf("%d. %dx%d\n", data->count, width, height);
+       g_print("%d. %dx%d\n", data->count, width, height);
 
        data->count++;
 
@@ -519,7 +528,7 @@ static bool capture_resolution_test_cb(int width, int height, void *user_data)
 
 static bool af_mode_foreach_cb(camera_attr_iso_e mode, void *user_data)
 {
-       printf("%d.%s\n", mode, af_scan[mode]);
+       g_print("%d.%s\n", mode, af_scan[mode]);
        return true;
 }
 
@@ -528,20 +537,20 @@ static bool exposure_mode_cb(camera_attr_af_mode_e mode, void *user_data)
        exposure_stack *data = (exposure_stack *)user_data;
 
        if (data == NULL) {
-               printf("NULL data\n");
+               g_print("NULL data\n");
                return false;
        }
 
        data->mode = mode;
        data->count++;
 
-       printf("%d.%s\n", mode, exposure_mode[mode]);
+       g_print("%d.%s\n", mode, exposure_mode[mode]);
        return true;
 }
 
 static bool iso_mode_cb(camera_attr_iso_e mode, void *user_data)
 {
-       printf("%d.%s\n", mode, iso_mode[mode]);
+       g_print("%d.%s\n", mode, iso_mode[mode]);
        return true;
 }
 
@@ -550,55 +559,55 @@ static bool camera_rotation_cb(camera_rotation_e mode, void *user_data)
        camera_rotation_stack *data = (camera_rotation_stack *)user_data;
 
        if (data == NULL) {
-               printf("NULL data\n");
+               g_print("NULL data\n");
                return false;
        }
 
        data->mode = mode;
        data->count++;
 
-       printf("%d.%s\n", mode, camera_rotation[mode]);
+       g_print("%d.%s\n", mode, camera_rotation[mode]);
 
        return true;
 }
 
 static bool preview_format_cb(camera_pixel_format_e mode, void *user_data)
 {
-       printf("%d.%s\n", mode, image_fmt[mode]);
+       g_print("%d.%s\n", mode, image_fmt[mode]);
        return true;
 }
 
 static bool white_balance_cb(camera_attr_whitebalance_e mode, void *user_data)
 {
-       printf("%d.%s\n", mode, wb[mode]);
+       g_print("%d.%s\n", mode, wb[mode]);
        return true;
 }
 
 static bool colortone_cb(camera_attr_effect_mode_e mode, void *user_data)
 {
-       printf("%d.%s\n", mode, ct[mode]);
+       g_print("%d.%s\n", mode, ct[mode]);
        return true;
 }
 
 static bool program_mode_cb(camera_attr_scene_mode_e mode, void *user_data)
 {
-       printf("%d.%s\n", mode, program_mode[mode]);
+       g_print("%d.%s\n", mode, program_mode[mode]);
        return true;
 }
 
 static bool strobe_mode_cb(camera_attr_flash_mode_e mode, void *user_data)
 {
-       printf("%d.%s\n", mode, strobe_mode[mode]);
+       g_print("%d.%s\n", mode, strobe_mode[mode]);
        return true;
 }
 
 static void _face_detected(camera_detected_face_s *faces, int count, void *user_data)
 {
-       printf("face detected!!\n");
+       g_print("face detected!!\n");
        int i;
 
        for (i = 0 ; i < count ; i++)
-               printf("%d) - %dx%d\n", faces[i].id, faces[i].x, faces[i].y);
+               g_print("%d) - %dx%d\n", faces[i].id, faces[i].x, faces[i].y);
 
        return;
 }
@@ -608,20 +617,20 @@ static void _file_write(char *path, void *data, int size)
        FILE *fp = NULL;
 
        if (!path || !data || size <= 0) {
-               printf("ERROR %p %p %d\n", path, data, size);
+               g_print("ERROR %p %p %d\n", path, data, size);
                return;
        }
 
        fp = fopen(path, "w");
        if (fp == NULL) {
-               printf("open error! [%s], errno %d\n", path, errno);
+               g_print("open error! [%s], errno %d\n", path, errno);
                return;
        } else {
-               printf("open success [%s]\n", path);
+               g_print("open success [%s]\n", path);
                if (fwrite(data, size, 1, fp) != 1)
-                       printf("write error! errno %d\n", errno);
+                       g_print("write error! errno %d\n", errno);
                else
-                       printf("write success [%s]\n", path);
+                       g_print("write success [%s]\n", path);
 
                fclose(fp);
                fp = NULL;
@@ -662,6 +671,9 @@ static void print_menu()
                g_print("\t=======================================\n");
                g_print("\t   '1' Video Capture - Front Camera\n");
                g_print("\t   '2' Video Capture - Rear Camera\n");
+               g_print("\t   '3' Add camera device state changed callback\n");
+               g_print("\t   '4' Remove camera device state changed callback\n");
+               g_print("\t   '5' Get camera device state\n");
                g_print("\t   'q' Exit\n");
                g_print("\t=======================================\n");
 
@@ -756,10 +768,10 @@ static void main_menu(gchar buf)
                        hcamcorder->isMultishot = TRUE;
                        int interval = 0, count = 0;
                        flush_stdin();
-                       printf("\ninput interval(ms)\n");
+                       g_print("\ninput interval(ms)\n");
                        err = scanf("%d", &interval);
                        flush_stdin();
-                       printf("\ninput count(ms) \n");
+                       g_print("\ninput count(ms) \n");
                        err = scanf("%d", &count);
                        camera_attr_set_image_quality(hcamcorder->camera, 100);
                        camera_set_capture_format(hcamcorder->camera, CAMERA_PIXEL_FORMAT_JPEG);
@@ -832,24 +844,24 @@ static void setting_menu(gchar buf)
                        err = scanf("%d", &idx);
                        int result = 0;
                        if (resolution_list.count > idx && idx >= 0) {
-                               printf("-----------------PREVIEW RESOLUTION (%dx%d)---------------------\n",
+                               g_print("-----------------PREVIEW RESOLUTION (%dx%d)---------------------\n",
                                        resolution_list.width[idx], resolution_list.height[idx]);
 
                                result = camera_set_preview_resolution(hcamcorder->camera,
                                        resolution_list.width[idx], resolution_list.height[idx]);
                        } else {
-                               printf("invalid input %d\n", idx);
+                               g_print("invalid input %d\n", idx);
                                result = -1;
                        }
                        resolution_list.count = 0;
                        if (result != 0)
-                               printf("FAIL\n");
+                               g_print("FAIL\n");
                        else
-                               printf("PASS\n");
+                               g_print("PASS\n");
                        break;
                case '1': /* Setting > Capture Resolution setting */
                        g_print("*Select the preview resolution!\n");
-                       printf("-----------------CAPTURE RESOLUTION TEST: ---------------------\n");
+                       g_print("-----------------CAPTURE RESOLUTION TEST: ---------------------\n");
                        resolution_list.count = 0;
 
                        camera_foreach_supported_capture_resolution(hcamcorder->camera,
@@ -862,17 +874,17 @@ static void setting_menu(gchar buf)
                                result = camera_set_capture_resolution(hcamcorder->camera,
                                        resolution_list.width[idx], resolution_list.height[idx]);
 
-                               printf("camera_set_capture_resolution with width =%d, height=%d ret=0x%x\n",
+                               g_print("camera_set_capture_resolution with width =%d, height=%d ret=0x%x\n",
                                        resolution_list.width[idx], resolution_list.height[idx], result);
                        } else {
-                               printf("invalid input %d\n", idx);
+                               g_print("invalid input %d\n", idx);
                                result = -1;
                        }
                        resolution_list.count = 0;
                        if (result != 0)
-                               printf("FAIL\n");
+                               g_print("FAIL\n");
                        else
-                               printf("PASS\n");
+                               g_print("PASS\n");
 
                        break;
                case '2': /* Setting > Digital zoom level */
@@ -1352,6 +1364,7 @@ void _preview_cb(camera_preview_data_s *frame, void *user_data)
 static gboolean mode_change(gchar buf)
 {
        int err = 0;
+       camera_device_state_e device_state = CAMERA_DEVICE_STATE_NULL;
        char display_type = '\0';
        bool check = FALSE;
 
@@ -1366,6 +1379,24 @@ static gboolean mode_change(gchar buf)
                hcamcorder->type = cam_info = CAMERA_DEVICE_CAMERA0;
                check = TRUE;
                break;
+       case '3':
+               err = camera_add_device_state_changed_cb(_camera_device_state_changed_cb,
+                       NULL, &g_camera_device_changed_cb_id);
+               g_print("add result 0x%x - cb id %d\n", err, g_camera_device_changed_cb_id);
+               return FALSE;
+       case '4':
+               if (g_camera_device_changed_cb_id > 0) {
+                       err = camera_remove_device_state_changed_cb(g_camera_device_changed_cb_id);
+                       g_camera_device_changed_cb_id = 0;
+                       g_print("remove result 0x%x\n", err);
+               } else {
+                       g_print("invalid callback id %d\n", g_camera_device_changed_cb_id);
+               }
+               return FALSE;
+       case '5':
+               err = camera_get_device_state(CAMERA_DEVICE_CAMERA0, &device_state);
+               g_print("get result 0x%x - state %d\n", err, device_state);
+               return FALSE;
        case 'q':
                g_print("\t Quit Camcorder Testsuite!!\n");
                hcamcorder->mode = -1;