New APIs are added 10/90310/1 accepted/tizen/3.0/ivi/20161011.062313 accepted/tizen/common/20160930.174727 accepted/tizen/ivi/20160930.083800 accepted/tizen/mobile/20160930.083701 accepted/tizen/tv/20160930.083740 accepted/tizen/wearable/20160930.083623 submit/tizen/20160930.030513 submit/tizen_3.0_ivi/20161010.000006
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 29 Sep 2016 10:36:08 +0000 (19:36 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 29 Sep 2016 10:36:08 +0000 (19:36 +0900)
New enum :
recorder_device_state_e
New function :
recorder_get_device_state
recorder_add_device_state_changed_cb
recorder_remove_device_state_changed_cb

[Version] 0.2.38
[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_20160929.1]

Change-Id: I250260e1259ac54c0366908e14754edb75c992f2
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
CMakeLists.txt
include/recorder.h
include/recorder_private.h
packaging/capi-media-recorder.spec
src/recorder.c
test/CMakeLists.txt
test/recorder_test.c

index 389fa2a..065f044 100644 (file)
@@ -9,7 +9,7 @@ SET(service "media")
 SET(submodule "recorder")
 
 # for package file
-SET(dependents "dlog capi-media-camera capi-media-audio-io mmsvc-recorder storage mused capi-media-sound-manager libtzplatform-config")
+SET(dependents "glib-2.0 gio-2.0 dlog capi-media-camera capi-media-audio-io mmsvc-recorder storage mused capi-media-sound-manager libtzplatform-config")
 SET(pc_dependents "capi-base-common capi-media-camera capi-media-audio-io capi-media-sound-manager")
 
 SET(fw_name "${project_prefix}-${service}-${submodule}")
index 682a2ee..fb9be7e 100644 (file)
@@ -161,6 +161,25 @@ typedef enum {
 } recorder_policy_e;
 
 /**
+ * @brief Enumeration for the recorder type.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       RECORDER_TYPE_AUDIO = 0,    /**< Audio only recorder */
+       RECORDER_TYPE_VIDEO         /**< Video recorder (audio is optional) */
+} recorder_type_e;
+
+/**
+ * @brief Enumeration for the recorder device state.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       RECORDER_DEVICE_STATE_IDLE = 0,     /**< No recording in progress */
+       RECORDER_DEVICE_STATE_RECORDING,    /**< Now recording */
+       RECORDER_DEVICE_STATE_PAUSED        /**< All recordings are paused */
+} recorder_device_state_e;
+
+/**
  * @}
 */
 
@@ -216,6 +235,16 @@ typedef void (*recorder_recording_status_cb)(unsigned long long elapsed_time, un
 typedef void (*recorder_state_changed_cb)(recorder_state_e previous , recorder_state_e current , bool by_policy, void *user_data);
 
 /**
+ * @brief Called when the recorder device state is changed.
+ * @since_tizen 3.0
+ * @param[in] type The recorder type
+ * @param[in] state The state of the recorder device
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see        recorder_add_device_state_changed_cb()
+ */
+typedef void (*recorder_device_state_changed_cb)(recorder_type_e type, recorder_device_state_e state, void *user_data);
+
+/**
  * @brief Called when the recorder is interrupted by a policy.
  * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
  * @param[in] policy        The policy that is interrupting the recorder
@@ -1154,6 +1183,50 @@ int recorder_unset_error_cb(recorder_h recorder);
 
 
 /**
+ * @brief Gets the state of recorder device.
+ * @since_tizen 3.0
+ * @param[in] type The recorder type
+ * @param[out] state The current state of the device
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RECORDER_ERROR_NONE Successful
+ * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RECORDER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #RECORDER_ERROR_NOT_SUPPORTED The feature is not supported
+ */
+int recorder_get_device_state(recorder_type_e type, recorder_device_state_e *state);
+
+/**
+ * @brief Registers a callback function to be called when the recorder 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 the registered callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RECORDER_ERROR_NONE Successful
+ * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RECORDER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #RECORDER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RECORDER_ERROR_NOT_SUPPORTED The feature is not supported
+ * @post This function will invoke recorder_device_state_changed_cb() when the recorder device's state changes.
+ * @see recorder_remove_device_state_changed_cb()
+ * @see recorder_device_state_changed_cb()
+ */
+int recorder_add_device_state_changed_cb(recorder_device_state_changed_cb callback, void *user_data, int *cb_id);
+
+/**
+ * @brief Unregisters a callback function.
+ * @since_tizen 3.0
+ * @param[in] cb_id The id of the registered callback
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RECORDER_ERROR_NONE Successful
+ * @retval #RECORDER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RECORDER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #RECORDER_ERROR_NOT_SUPPORTED The feature is not supported
+ * @see recorder_add_device_state_changed_cb()
+ */
+int recorder_remove_device_state_changed_cb(int cb_id);
+
+/**
  * @}
  */
 
index 76608dc..6d29b75 100644 (file)
@@ -148,6 +148,12 @@ typedef struct _camera_cli_s {
        void *cb_info;
 } camera_cli_s;
 
+typedef struct _recorder_cb_info {
+       int id;
+       void *callback;
+       void *user_data;
+} recorder_cb_info;
+
 int __convert_recorder_error_code(const char *func, int code);
 
 #ifdef __cplusplus
index 692bb3e..cdd8f1d 100644 (file)
@@ -1,11 +1,13 @@
 Name:       capi-media-recorder
 Summary:    A Recorder API
-Version:    0.2.37
+Version:    0.2.38
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 BuildRequires:  cmake
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(capi-media-camera)
@@ -15,6 +17,7 @@ BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(mused)
 BuildRequires:  pkgconfig(evas)
 BuildRequires:  pkgconfig(elementary)
+BuildRequires:  pkgconfig(appcore-efl)
 BuildRequires:  pkgconfig(capi-media-tool)
 BuildRequires:  pkgconfig(capi-media-audio-io)
 BuildRequires:  pkgconfig(capi-media-sound-manager)
index a5e453a..c8d52c2 100644 (file)
@@ -29,6 +29,7 @@
 #include <muse_core_module.h>
 #include <recorder_private.h>
 #include <glib.h>
+#include <gio/gio.h>
 #include <dlog.h>
 #include <tzplatform_config.h>
 
 #endif
 #define LOG_TAG "TIZEN_N_RECORDER"
 
+/* for device changed callback */
+static GMutex g_rec_dev_state_changed_cb_lock;
+static GList *g_rec_dev_state_changed_cb_list;
+static int g_rec_dev_state_changed_cb_id;
+static GDBusConnection *g_rec_dev_state_changed_cb_conn;
+static guint g_rec_dev_state_changed_cb_subscribe_id;
+static recorder_device_state_e g_rec_dev_last_state;
+
+
+static void __recorder_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;
+       recorder_type_e type = RECORDER_TYPE_AUDIO;
+       recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
+       GList *tmp_list = NULL;
+       recorder_cb_info *info = NULL;
+
+       g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
+
+       if (!g_rec_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);
+
+       /* get type only from message */
+       type = value >> 16;
+
+       if (recorder_get_device_state(type, &state) != RECORDER_ERROR_NONE) {
+               LOGE("failed to get recorder device state");
+               goto _DONE;
+       }
+
+       LOGD("type %d, state %d", type, state);
+
+       if (state == g_rec_dev_last_state) {
+               LOGW("no need to call recorder device state changed cb [state %d]", state);
+               goto _DONE;
+       }
+
+       g_rec_dev_last_state = state;
+
+       tmp_list = g_rec_dev_state_changed_cb_list;
+
+       do {
+               info = (recorder_cb_info *)tmp_list->data;
+
+               if (info) {
+                       if (info->callback) {
+                               LOGD("start id[%d] callback", info->id);
+                               ((recorder_device_state_changed_cb)info->callback)(type, 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_rec_dev_state_changed_cb_lock);
+
+       return;
+}
+
 
 static int _recorder_import_tbm_key(tbm_bufmgr bufmgr, unsigned int tbm_key, tbm_bo *bo, tbm_bo_handle *bo_handle)
 {
@@ -822,22 +893,27 @@ static void *_recorder_msg_recv_func(gpointer data)
                                cb_info->api_ret[api] = ret;
                                cb_info->api_activating[api] = 1;
 
-                               switch (api) {
-                               case MUSE_RECORDER_API_CREATE:
-                                       if (ret != RECORDER_ERROR_NONE) {
-                                               g_atomic_int_set(&cb_info->msg_recv_running, 0);
-                                               LOGE("create error 0x%x. closing..", ret);
-                                       }
-                                       break;
-                               case MUSE_RECORDER_API_DESTROY:
-                                       if (ret == RECORDER_ERROR_NONE) {
-                                               g_atomic_int_set(&cb_info->msg_recv_running, 0);
-                                               LOGD("destroy done. closing..");
+                               if (api == MUSE_RECORDER_API_GET_DEVICE_STATE) {
+                                       g_atomic_int_set(&cb_info->msg_recv_running, 0);
+                                       LOGD("get device state done. close client cb handler");
+                               } else {
+                                       switch (api) {
+                                       case MUSE_RECORDER_API_CREATE:
+                                               if (ret != RECORDER_ERROR_NONE) {
+                                                       g_atomic_int_set(&cb_info->msg_recv_running, 0);
+                                                       LOGE("create error 0x%x. closing..", ret);
+                                               }
+                                               break;
+                                       case MUSE_RECORDER_API_DESTROY:
+                                               if (ret == RECORDER_ERROR_NONE) {
+                                                       g_atomic_int_set(&cb_info->msg_recv_running, 0);
+                                                       LOGD("destroy done. closing..");
+                                               }
+                                               break;
+                                       default:
+                                               _recorder_get_api_operation(api, cb_info, parse_str[i]);
+                                               break;
                                        }
-                                       break;
-                               default:
-                                       _recorder_get_api_operation(api, cb_info, parse_str[i]);
-                                       break;
                                }
 
                                g_cond_signal(&cb_info->api_cond[api]);
@@ -3009,3 +3085,239 @@ int  recorder_attr_get_orientation_tag(recorder_h recorder, recorder_rotation_e
 
        return ret;
 }
+
+
+int recorder_get_device_state(recorder_type_e type, recorder_device_state_e *state)
+{
+       int ret = RECORDER_ERROR_NONE;
+       int sock_fd = -1;
+       int get_device_state = 0;
+       char *send_msg = NULL;
+       muse_recorder_api_e api = MUSE_RECORDER_API_GET_DEVICE_STATE;
+       recorder_cb_info_s *cb_info = NULL;
+
+       if (!state) {
+               LOGE("NULL pointer");
+               return RECORDER_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGD("Enter - type %d", type);
+
+       sock_fd = muse_core_client_new();
+       if (sock_fd < 0) {
+               LOGE("muse_core_client_new failed - returned fd %d", sock_fd);
+               ret = RECORDER_ERROR_INVALID_OPERATION;
+               goto _GET_DEVICE_STATE_EXIT;
+       }
+
+       send_msg = muse_core_msg_json_factory_new(api,
+               MUSE_TYPE_INT, "module", MUSE_RECORDER,
+               MUSE_TYPE_INT, PARAM_RECORDER_TYPE, type,
+               NULL);
+       if (!send_msg) {
+               LOGE("NULL msg");
+               ret = RECORDER_ERROR_OUT_OF_MEMORY;
+               goto _GET_DEVICE_STATE_EXIT;
+       }
+
+       LOGD("sock_fd : %d, msg : %s", sock_fd, send_msg);
+
+       ret = muse_core_ipc_send_msg(sock_fd, send_msg);
+
+       muse_core_msg_json_factory_free(send_msg);
+       send_msg = NULL;
+
+       if (ret < 0) {
+               LOGE("send msg failed %d", errno);
+               ret = RECORDER_ERROR_INVALID_OPERATION;
+               goto _GET_DEVICE_STATE_EXIT;
+       }
+
+       cb_info = _recorder_client_callback_new(sock_fd, false);
+       if (cb_info == NULL) {
+               ret = RECORDER_ERROR_OUT_OF_MEMORY;
+               goto _GET_DEVICE_STATE_EXIT;
+       }
+
+       sock_fd = -1;
+
+       ret = _recorder_client_wait_for_cb_return(api, cb_info, RECORDER_CB_TIMEOUT);
+       if (ret != RECORDER_ERROR_NONE) {
+               LOGE("API_CREATE failed 0x%x", ret);
+               goto _GET_DEVICE_STATE_EXIT;
+       }
+
+       if (ret == RECORDER_ERROR_NONE) {
+               muse_recorder_msg_get(get_device_state, cb_info->recv_msg);
+               *state = (recorder_device_state_e)get_device_state;
+               LOGD("device state %d", *state);
+       } else {
+               LOGE("failed 0x%x", ret);
+       }
+
+_GET_DEVICE_STATE_EXIT:
+       if (cb_info) {
+               _recorder_client_callback_destroy(cb_info);
+               cb_info = NULL;
+       }
+
+       if (sock_fd > -1) {
+               muse_core_connection_close(sock_fd);
+               sock_fd = -1;
+       }
+
+       return ret;
+}
+
+
+int recorder_add_device_state_changed_cb(recorder_device_state_changed_cb callback, void *user_data, int *cb_id)
+{
+       int ret = RECORDER_ERROR_NONE;
+       recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
+       recorder_cb_info *info = NULL;
+
+       if (!callback || !cb_id) {
+               LOGE("invalid pointer %p %p", callback, cb_id);
+               return RECORDER_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
+
+       /* check recorder support */
+       ret = recorder_get_device_state(RECORDER_TYPE_AUDIO, &state);
+       if (ret != RECORDER_ERROR_NONE) {
+               LOGE("get device state failed");
+               g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
+               return ret;
+       }
+
+       g_rec_dev_last_state = state;
+
+       info = g_new0(recorder_cb_info, 1);
+       if (!info) {
+               LOGE("info failed");
+               ret = RECORDER_ERROR_OUT_OF_MEMORY;
+               goto _DONE;
+       }
+
+       info->id = ++g_rec_dev_state_changed_cb_id;
+       info->callback = (void *)callback;
+
+       *cb_id = info->id;
+
+       /* subscribe dbus signal for camera state change */
+       if (!g_rec_dev_state_changed_cb_conn) {
+               g_rec_dev_state_changed_cb_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+               if (!g_rec_dev_state_changed_cb_conn) {
+                       LOGE("failed to get gdbus connection");
+                       ret = RECORDER_ERROR_INVALID_OPERATION;
+                       goto _DONE;
+               }
+
+               LOGD("subscribe signal %s - %s - %s",
+                       MM_CAMCORDER_DBUS_OBJECT,
+                       MM_CAMCORDER_DBUS_INTERFACE_RECORDER,
+                       MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED);
+
+               g_rec_dev_state_changed_cb_subscribe_id = g_dbus_connection_signal_subscribe(g_rec_dev_state_changed_cb_conn,
+                       NULL, MM_CAMCORDER_DBUS_INTERFACE_RECORDER, MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED, MM_CAMCORDER_DBUS_OBJECT, NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)__recorder_device_state_changed_cb, NULL, NULL);
+               if (!g_rec_dev_state_changed_cb_subscribe_id) {
+                       LOGE("failed to get gdbus connection");
+                       ret = RECORDER_ERROR_INVALID_OPERATION;
+                       goto _DONE;
+               }
+
+               LOGD("signal subscribe id %u", g_rec_dev_state_changed_cb_subscribe_id);
+       }
+
+       g_rec_dev_state_changed_cb_list = g_list_prepend(g_rec_dev_state_changed_cb_list, (gpointer)info);
+
+       LOGD("callback id %d", info->id);
+
+_DONE:
+       if (ret != RECORDER_ERROR_NONE) {
+               if (info) {
+                       g_free(info);
+                       info = NULL;
+               }
+
+               if (g_rec_dev_state_changed_cb_conn) {
+                       g_object_unref(g_rec_dev_state_changed_cb_conn);
+                       g_rec_dev_state_changed_cb_conn = NULL;
+               }
+       }
+
+       g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
+
+       return ret;
+}
+
+
+int recorder_remove_device_state_changed_cb(int cb_id)
+{
+       int ret = RECORDER_ERROR_NONE;
+       recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
+       GList *tmp_list = NULL;
+       recorder_cb_info *info = NULL;
+
+       /* check recorder support */
+       ret = recorder_get_device_state(RECORDER_TYPE_AUDIO, &state);
+       if (ret != RECORDER_ERROR_NONE) {
+               LOGE("get device state failed");
+               return ret;
+       }
+
+       g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
+
+       if (!g_rec_dev_state_changed_cb_list) {
+               LOGE("there is no callback info");
+               ret = RECORDER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       tmp_list = g_rec_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_rec_dev_state_changed_cb_list = g_list_remove(g_rec_dev_state_changed_cb_list, info);
+
+                       g_free(info);
+                       info = NULL;
+
+                       if (!g_rec_dev_state_changed_cb_list) {
+                               /* no remained callback */
+                               if (g_rec_dev_state_changed_cb_conn) {
+                                       /* unsubscribe signal */
+                                       g_dbus_connection_signal_unsubscribe(g_rec_dev_state_changed_cb_conn, g_rec_dev_state_changed_cb_subscribe_id);
+                                       g_rec_dev_state_changed_cb_subscribe_id = 0;
+
+                                       /* unref connection */
+                                       g_object_unref(g_rec_dev_state_changed_cb_conn);
+                                       g_rec_dev_state_changed_cb_conn = NULL;
+                               }
+                       }
+
+                       LOGD("id %d callback removed", cb_id);
+                       ret = RECORDER_ERROR_NONE;
+
+                       goto _DONE;
+               }
+       } while (tmp_list);
+
+       LOGE("id %d callback not found", cb_id);
+       ret = RECORDER_ERROR_INVALID_PARAMETER;
+
+_DONE:
+       g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
+
+       return ret;
+}
index 88541b7..d9c63c0 100644 (file)
@@ -5,7 +5,7 @@ SET(fw_test "${fw_name}-test")
 #link_directories(${CMAKE_SOURCE_DIR}/../)
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_test} REQUIRED elementary evas capi-media-sound-manager)
+pkg_check_modules(${fw_test} REQUIRED elementary evas capi-media-sound-manager appcore-efl)
 FOREACH(flag ${${fw_test}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
     MESSAGE(${flag})
index afa19cb..7a22a0c 100644 (file)
 #include <sys/time.h>
 #include <camera.h>
 #include <recorder.h>
-#include <dlog.h>
-#include <Ecore.h>
 #include <Elementary.h>
 #include <sound_manager.h>
+#include <appcore-efl.h>
 
 /*-----------------------------------------------------------------------
   |    GLOBAL VARIABLE DEFINITIONS:                                       |
   -----------------------------------------------------------------------*/
 #define EXPORT_API __attribute__((__visibility__("default")))
 
-#define PACKAGE "recorder_testsuite"
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 #define LOG_TAG "RECORDER_TESTSUITE"
 
-GMainLoop *g_loop;
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+#define PACKAGE "recorder_test"
+
+
+static int app_create(void *data);
+static int app_terminate(void *data);
+
+struct _appdata {
+       Evas_Object *win;
+       Evas_Object *eo;
+       Evas_Object *bg;
+       Evas_Object *rect;
+};
+typedef struct _appdata appdata;
+
+struct appcore_ops ops = {
+       .create = app_create,
+       .terminate = app_terminate,
+};
+
+appdata ad;
 GIOChannel *stdin_channel;
 int resolution_set;
 int g_current_state;
@@ -54,7 +74,7 @@ int  cam_info;
 int recorder_state;
 int multishot_num;
 static GTimer *timer = NULL;
-void *display;
+static int g_recorder_device_changed_cb_id;
 
 /*-----------------------------------------------------------------------
   |    GLOBAL CONSTANT DEFINITIONS:                                       |
@@ -109,7 +129,7 @@ void *display;
                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)
@@ -150,6 +170,7 @@ enum {
 };
 
 enum {
+       MENU_STATE_INIT,
        MENU_STATE_MAIN,
        MENU_STATE_SETTING,
        MENU_STATE_NUM,
@@ -414,118 +435,124 @@ const char *visible_mode[] = {
 static void print_menu();
 static gboolean cmd_input(GIOChannel *channel);
 static gboolean init(int type);
-static gboolean mode_change();
+static gboolean mode_change(gchar buf);
 
 
-bool preview_resolution_cb(int width, int height, void *user_data)
+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++;
 
        return true;
 }
 
-bool af_mode_foreach_cb(camera_attr_iso_e mode , 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;
 }
 
-bool exposure_mode_cb(camera_attr_af_mode_e mode , void *user_data)
+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;
 }
 
-bool iso_mode_cb(camera_attr_iso_e mode , void *user_data)
+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;
 }
 
-bool camera_rotation_cb(camera_rotation_e mode , void *user_data)
+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;
 }
 
-bool preview_format_cb(camera_pixel_format_e mode , void *user_data)
+static bool white_balance_cb(camera_attr_whitebalance_e mode , void *user_data)
 {
-       printf("%d.%s\n", mode, image_fmt[mode]);
+       g_print("%d.%s\n", mode, wb[mode]);
        return true;
 }
 
-bool white_balance_cb(camera_attr_whitebalance_e mode , void *user_data)
+static bool colortone_cb(camera_attr_effect_mode_e mode , void *user_data)
 {
-       printf("%d.%s\n", mode, wb[mode]);
+       g_print("%d.%s\n", mode, ct[mode]);
        return true;
 }
 
-bool colortone_cb(camera_attr_effect_mode_e mode , void *user_data)
+static bool program_mode_cb(camera_attr_scene_mode_e mode , void *user_data)
 {
-       printf("%d.%s\n", mode, ct[mode]);
+       g_print("%d.%s\n", mode, program_mode[mode]);
        return true;
 }
 
-bool program_mode_cb(camera_attr_scene_mode_e mode , void *user_data)
+static bool strobe_mode_cb(camera_attr_flash_mode_e mode , void *user_data)
 {
-       printf("%d.%s\n", mode, program_mode[mode]);
+       g_print("%d.%s\n", mode, strobe_mode[mode]);
        return true;
 }
 
-bool strobe_mode_cb(camera_attr_flash_mode_e mode , void *user_data)
+static void _face_detected(camera_detected_face_s *faces, int count, void *user_data)
 {
-       printf("%d.%s\n", mode, strobe_mode[mode]);
-       return true;
+       int i;
+
+       g_print("face detected!!\n");
+
+       for (i = 0 ; i < count ; i++)
+               g_print("%d) - %dx%d\n", faces[i].id, faces[i].x, faces[i].y);
+
+       return;
 }
 
-void _face_detected(camera_detected_face_s *faces, int count, void *user_data)
+static void _state_changed_cb(recorder_state_e previous_state, recorder_state_e current_state, bool by_policy, void *user_data)
 {
-       printf("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("\n\tstate changed[by_policy:%d] : %d -> %d\n\n", by_policy, previous_state, current_state);
+       return;
 }
 
-void _state_changed_cb(recorder_state_e previous_state, recorder_state_e current_state, bool by_policy, void *user_data)
+static void _recorder_device_state_changed_cb(recorder_type_e type, recorder_device_state_e state, void *user_data)
 {
-       printf("\n\tstate changed[by_policy:%d] : %d -> %d\n\n", by_policy, previous_state, current_state);
+       g_print("\nrecorder device[%d] state changed to %d\n", type, state);
+       return;
 }
 
-void _recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data)
+static void _recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data)
 {
        static unsigned long long elapsed = -1;
+
        if (elapsed != elapsed_time / 1000) {
                unsigned long temp_time;
                unsigned long long hour, minute, second;
@@ -535,14 +562,17 @@ void _recording_status_cb(unsigned long long elapsed_time, unsigned long long fi
                temp_time = elapsed % 3600;
                minute = temp_time / 60;
                second = temp_time % 60;
-               printf("\n\tCurrent Time - %lld:%lld:%lld, filesize %lld KB\n\n",
+               g_print("\n\tCurrent Time - %lld:%lld:%lld, filesize %lld KB\n\n",
                                hour, minute, second, file_size);
        }
+
+       return;
 }
 
-void _recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data)
+static void _recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data)
 {
-       printf("\n\tRECORDING LIMIT REACHED [type: %d]\n\n", type);
+       g_print("\n\tRECORDING LIMIT REACHED [type: %d]\n\n", type);
+       return;
 }
 
 
@@ -550,34 +580,34 @@ static inline void flush_stdin()
 {
        int ch;
        while ((ch = getchar()) != EOF && ch != '\n');
+       return;
 }
 
 static bool _release_idle_event_callback(void *data)
 {
-       printf("destroy recorder handle\n\n");
+       g_print("destroy recorder handle\n\n");
 
        recorder_destroy(hcamcorder->recorder);
        hcamcorder->recorder = NULL;
-
-       hcamcorder->menu_state = MENU_STATE_MAIN;
-       mode_change();
+       hcamcorder->menu_state = MENU_STATE_INIT;
+       print_menu();
 
        return 0;
 }
 
 static void _recorder_error_cb(int error, recorder_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 RECORDER_ERROR_RESOURCE_CONFLICT:
-               printf("\t\t[RECORDER_ERROR_RESOURCE_CONFLICT]\n\n");
+               g_print("\t\t[RECORDER_ERROR_RESOURCE_CONFLICT]\n\n");
                break;
        case RECORDER_ERROR_SECURITY_RESTRICTED:
-               printf("\t\t[RECORDER_ERROR_SECURITY_RESTRICTED]\n\n");
+               g_print("\t\t[RECORDER_ERROR_SECURITY_RESTRICTED]\n\n");
                break;
        case RECORDER_ERROR_SERVICE_DISCONNECTED:
-               printf("\t\t[RECORDER_ERROR_SERVICE_DISCONNECTED]\n\n");
+               g_print("\t\t[RECORDER_ERROR_SERVICE_DISCONNECTED]\n\n");
                g_idle_add_full(G_PRIORITY_DEFAULT,
                        (GSourceFunc)_release_idle_event_callback,
                        NULL, NULL);
@@ -592,7 +622,21 @@ static void _recorder_error_cb(int error, recorder_state_e current_state, void *
 
 static void print_menu()
 {
-       switch (hcamcorder->menu_state) {
+       switch (hcamcorder->menu_state) {
+       case MENU_STATE_INIT:
+               g_print("\n\t=======================================\n");
+               g_print("\t   RECORDER_TESTSUIT\n");
+               g_print("\t=======================================\n");
+               g_print("\t   '1' Video Capture - Rear Camera\n");
+               g_print("\t   '2' Audio Recording - MIC\n");
+               g_print("\t   '3' Audio Recording - MODEM\n");
+               g_print("\t   '4' Add recorder device changed callback\n");
+               g_print("\t   '5' Remove recorder device changed callback\n");
+               g_print("\t   '6' Get recorder device state\n");
+               g_print("\t   'q' Exit\n");
+               g_print("\t=======================================\n");
+               g_print("\t  Choose the menu :\n\t");
+               break;
        case MENU_STATE_MAIN:
                if (hcamcorder->mode == MODE_VIDEO_CAPTURE) {
                        g_print("\n\t=======================================\n");
@@ -674,7 +718,7 @@ static void print_menu()
                break;
 
        default:
-               LOGE("unknow menu state !!\n");
+               g_print("unknow menu state !!\n");
                break;
        }
 
@@ -696,7 +740,7 @@ static void main_menu(gchar buf)
                                err = recorder_start(hcamcorder->recorder);
 
                                if (err != 0)
-                                       LOGE("Rec start camcorder_record 0x%x", err);
+                                       g_print("Rec start camcorder_record 0x%x\n", err);
 
                                recorder_state = RECORDER_STATE_RECORDING;
                                break;
@@ -706,8 +750,8 @@ static void main_menu(gchar buf)
                                break;
 
                        case 'b': /* back */
-                               hcamcorder->menu_state = MENU_STATE_MAIN;
-                               mode_change();
+                               hcamcorder->menu_state = MENU_STATE_INIT;
+                               print_menu();
                                break;
 
                        default:
@@ -721,7 +765,7 @@ static void main_menu(gchar buf)
                                err = recorder_pause(hcamcorder->recorder);
 
                                if (err < 0)
-                                       LOGE("Rec pause camcorder_pause  = %x", err);
+                                       g_print("Rec pause camcorder_pause  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_PAUSED;
                                break;
@@ -730,7 +774,7 @@ static void main_menu(gchar buf)
                                g_print("*Resume!\n");
                                err = recorder_start(hcamcorder->recorder);
                                if (err < 0)
-                                       LOGE("Rec start camcorder_record  = %x", err);
+                                       g_print("Rec start camcorder_record  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_RECORDING;
                                break;
@@ -741,7 +785,7 @@ static void main_menu(gchar buf)
                                err = recorder_cancel(hcamcorder->recorder);
 
                                if (err < 0)
-                                       LOGE("Cancel recording camcorder_cancel  = %x", err);
+                                       g_print("Cancel recording camcorder_cancel  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_NONE;
                                break;
@@ -753,7 +797,7 @@ static void main_menu(gchar buf)
                                err = recorder_commit(hcamcorder->recorder);
 
                                if (err < 0)
-                                       LOGE("Save recording recorder_commit  = %x", err);
+                                       g_print("Save recording recorder_commit  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_NONE;
                                break;
@@ -763,7 +807,7 @@ static void main_menu(gchar buf)
                                break;
                        } /* switch */
                } else {
-                       LOGE("Wrong camcorder state, check status!!");
+                       g_print("Wrong camcorder state, check status!!\n");
                }
        } else if (hcamcorder->mode == MODE_AUDIO) {
                if (recorder_state == RECORDER_STATE_NONE) {
@@ -775,14 +819,14 @@ static void main_menu(gchar buf)
                                err = recorder_start(hcamcorder->recorder);
 
                                if (err < 0)
-                                       LOGE("Rec start camcorder_record  = %x", err);
+                                       g_print("Rec start camcorder_record  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_RECORDING;
                                break;
 
                        case 'b': /* back */
-                               hcamcorder->menu_state = MENU_STATE_MAIN;
-                               mode_change();
+                               hcamcorder->menu_state = MENU_STATE_INIT;
+                               print_menu();
                                break;
 
                        default:
@@ -796,7 +840,7 @@ static void main_menu(gchar buf)
                                err = recorder_pause(hcamcorder->recorder);
 
                                if (err < 0)
-                                       LOGE("Rec pause camcorder_pause  = %x", err);
+                                       g_print("Rec pause camcorder_pause  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_PAUSED;
                                break;
@@ -805,7 +849,7 @@ static void main_menu(gchar buf)
                                g_print("*Resume!\n");
                                err = recorder_start(hcamcorder->recorder);
                                if (err < 0)
-                                       LOGE("Rec start camcorder_record  = %x", err);
+                                       g_print("Rec start camcorder_record  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_RECORDING;
                                break;
@@ -815,7 +859,7 @@ static void main_menu(gchar buf)
                                err = recorder_cancel(hcamcorder->recorder);
 
                                if (err < 0)
-                                       LOGE("Cancel recording camcorder_cancel  = %x", err);
+                                       g_print("Cancel recording camcorder_cancel  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_NONE;
                                break;
@@ -826,7 +870,7 @@ static void main_menu(gchar buf)
                                err = recorder_commit(hcamcorder->recorder);
 
                                if (err < 0)
-                                       LOGE("Save recording recorder_commit  = %x", err);
+                                       g_print("Save recording recorder_commit  = %x\n", err);
 
                                recorder_state = RECORDER_STATE_NONE;
                                break;
@@ -836,12 +880,12 @@ static void main_menu(gchar buf)
                        break;
                        }
                } else {
-                       LOGE("Wrong camcorder state, check status!!");
+                       g_print("Wrong camcorder state, check status!!\n");
                }
        } else {
                g_print("\t Invalid mode, back to upper menu \n");
-               hcamcorder->menu_state = MENU_STATE_MAIN;
-               mode_change();
+               hcamcorder->menu_state = MENU_STATE_INIT;
+               print_menu();
        }
 }
 
@@ -871,22 +915,22 @@ 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 = recorder_set_video_resolution(hcamcorder->recorder,
                                        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 '2': /* Setting > Digital zoom level */
@@ -1055,7 +1099,7 @@ static void setting_menu(gchar buf)
                        camera_attr_get_brightness_range(hcamcorder->camera, &min, &max);
 
                        flush_stdin();
-                       g_print("\n Select  brightness min (%d) -max(%d)", min, max);
+                       g_print("\n Select  brightness min (%d) -max(%d)\n", min, max);
                        err = scanf("%d", &idx);
                        bret = camera_attr_set_brightness(hcamcorder->camera, idx);
                        break;
@@ -1065,7 +1109,7 @@ static void setting_menu(gchar buf)
                        camera_attr_get_contrast_range(hcamcorder->camera, &min, &max);
 
                        flush_stdin();
-                       g_print("\n Select  Contrast min(%d)-max(%d)", min, max);
+                       g_print("\n Select  Contrast min(%d)-max(%d)\n", min, max);
                        err = scanf("%d", &idx);
                        bret = camera_attr_set_contrast(hcamcorder->camera, idx);
                        break;
@@ -1145,7 +1189,7 @@ static void setting_menu(gchar buf)
                                if (idx >= 0 && idx < 2)
                                        bret = camera_start_face_detection(hcamcorder->camera, _face_detected, NULL);
                        } else {
-                               g_print("face detection_not supported");
+                               g_print("face detection_not supported\n");
                        }
 
                        break;
@@ -1256,11 +1300,11 @@ static gboolean cmd_input(GIOChannel *channel)
        gsize read_size;
        GError *g_error = NULL;
 
-       LOGD("ENTER");
+       g_print("\n\tENTER\n");
 
        g_io_channel_read_line(channel, &buf, &read_size, NULL, &g_error);
        if (g_error) {
-               LOGD("g_io_channel_read_chars error");
+               g_print("\n\tg_io_channel_read_chars error\n");
                g_error_free(g_error);
                g_error = NULL;
        }
@@ -1268,8 +1312,11 @@ static gboolean cmd_input(GIOChannel *channel)
        if (buf) {
                g_strstrip(buf);
 
-               LOGD("Menu Status : %d", hcamcorder->menu_state);
+               g_print("\n\tMenu Status : %d\n", hcamcorder->menu_state);
                switch (hcamcorder->menu_state) {
+               case MENU_STATE_INIT:
+                       mode_change(buf[0]);
+                       break;
                case MENU_STATE_MAIN:
                        main_menu(buf[0]);
                        break;
@@ -1285,7 +1332,7 @@ static gboolean cmd_input(GIOChannel *channel)
 
                print_menu();
        } else {
-               LOGD("No read input");
+               g_print("\n\tNo read input\n");
        }
 
        return TRUE;
@@ -1307,42 +1354,42 @@ static gboolean init(int type)
        if (type == MODE_VIDEO_CAPTURE) {
                err = recorder_set_file_format(hcamcorder->recorder, RECORDER_FILE_FORMAT_MP4);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_audio_device(hcamcorder->recorder, RECORDER_AUDIO_DEVICE_MIC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_set_audio_encoder(hcamcorder->recorder, RECORDER_AUDIO_CODEC_AAC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_set_video_encoder(hcamcorder->recorder, RECORDER_VIDEO_CODEC_MPEG4);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_video_encoder_bitrate(hcamcorder->recorder, VIDEO_ENCODE_BITRATE);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_audio_samplerate(hcamcorder->recorder, AUDIO_SOURCE_SAMPLERATE_AAC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_audio_channel(hcamcorder->recorder, AUDIO_SOURCE_CHANNEL_AAC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_set_filename(hcamcorder->recorder, TARGET_FILENAME_VIDEO);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
        } else if (type == MODE_AUDIO) {
@@ -1351,42 +1398,42 @@ static gboolean init(int type)
         *=================================================================================*/
                err = recorder_set_file_format(hcamcorder->recorder, RECORDER_FILE_FORMAT_MP4);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_audio_device(hcamcorder->recorder, RECORDER_AUDIO_DEVICE_MIC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_set_audio_encoder(hcamcorder->recorder, RECORDER_AUDIO_CODEC_AAC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_audio_samplerate(hcamcorder->recorder, AUDIO_SOURCE_SAMPLERATE_AAC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_audio_channel(hcamcorder->recorder, AUDIO_SOURCE_CHANNEL_AAC);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_set_filename(hcamcorder->recorder, TARGET_FILENAME_AUDIO);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_time_limit(hcamcorder->recorder, 360000);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
                err = recorder_attr_set_audio_encoder_bitrate(hcamcorder->recorder, 128000);
                if (err < 0) {
-                       LOGE("Init fail. (%x)", err);
+                       g_print("Init fail. (%x)\n", err);
                        goto ERROR;
                }
        }
@@ -1396,19 +1443,19 @@ static gboolean init(int type)
        recorder_set_recording_status_cb(hcamcorder->recorder, _recording_status_cb, NULL);
        recorder_set_recording_limit_reached_cb(hcamcorder->recorder, _recording_limit_reached_cb, NULL);
 
-       LOGD("Init DONE.");
+       g_print("Init DONE.\n");
 
        return TRUE;
 
 ERROR:
-       LOGE("init failed.");
+       g_print("init failed.\n");
        return FALSE;
 }
 
 static gboolean init_handle()
 {
        hcamcorder->mode = MODE_VIDEO_CAPTURE;  /* image(capture)/video(recording) mode */
-       hcamcorder->menu_state = MENU_STATE_MAIN;
+       hcamcorder->menu_state = MENU_STATE_INIT;
        hcamcorder->isMute = FALSE;
        hcamcorder->elapsed_time = 0;
        hcamcorder->fps = SRC_VIDEO_FRAME_RATE_15; /*SRC_VIDEO_FRAME_RATE_30;*/
@@ -1426,267 +1473,322 @@ static void _sound_stream_focus_state_changed_cb(sound_stream_info_h stream_info
 /**
  * This function is to change camcorder mode.
  *
- * @param    type    [in]    image(capture)/video(recording) mode
+ * @param    buf    [in]    user input
  *
  * @return   This function returns TRUE/FALSE
  * @remark
  * @see      other functions
  */
-static gboolean mode_change()
+static gboolean mode_change(gchar buf)
 {
        int err = RECORDER_ERROR_NONE;
        int state = RECORDER_STATE_NONE;
        char media_type = '\0';
        bool check = FALSE;
+       recorder_device_state_e device_state = RECORDER_DEVICE_STATE_IDLE;
+
+       g_get_current_time(&previous);
+       g_timer_reset(timer);
 
        if (hcamcorder->recorder) {
                err = recorder_get_state(hcamcorder->recorder, (recorder_state_e*)&state);
                if (state != RECORDER_STATE_NONE) {
                        if (state == RECORDER_STATE_RECORDING ||
                                        state == RECORDER_STATE_PAUSED) {
-                               LOGD("recorder_cancel");
+                               g_print("recorder_cancel\n");
                                err = recorder_cancel(hcamcorder->recorder);
                                if (err != RECORDER_ERROR_NONE) {
-                                       LOGE("exit recorder_cancel failed 0x%x", err);
+                                       g_print("exit recorder_cancel failed 0x%x\n", err);
                                        return FALSE;
                                }
                        }
 
                        err = recorder_get_state(hcamcorder->recorder, (recorder_state_e*)&state);
                        if (state == RECORDER_STATE_READY) {
-                               LOGD("recorder_unprepare");
+                               g_print("recorder_unprepare\n");
                                recorder_unprepare(hcamcorder->recorder);
                        }
 
                        err = recorder_get_state(hcamcorder->recorder, (recorder_state_e*)&state);
                        if (state == RECORDER_STATE_CREATED) {
-                               LOGD("recorder_destroy");
+                               g_print("recorder_destroy\n");
                                err = recorder_destroy(hcamcorder->recorder);
                                if (err == RECORDER_ERROR_NONE) {
-                                       LOGD("recorder_destroy done");
+                                       g_print("recorder_destroy done\n");
                                        hcamcorder->recorder = NULL;
                                }
                        }
                }
-       } else {
-               LOGW("NULL handle");
        }
 
        init_handle();
 
-       g_get_current_time(&previous);
-       g_timer_reset(timer);
+       switch (buf) {
+       case '1':
+               hcamcorder->mode = MODE_VIDEO_CAPTURE;
 
-       while (!check) {
-               g_print("\n\t=======================================\n");
-               g_print("\t   RECORDER_TESTSUIT\n");
-               g_print("\t=======================================\n");
-               g_print("\t   '1' Video Capture - Rear Camera\n");
-               g_print("\t   '2' Audio Recording - MIC\n");
-               g_print("\t   '3' Audio Recording - MODEM\n");
-               g_print("\t   'q' Exit\n");
-               g_print("\t=======================================\n");
-
-               g_print("\t  Enter the media type:\n\t");
+               g_print("camera_create\n");
 
-               err = scanf("%c", &media_type);
-               if (err == EOF) {
-                       g_print("\t!!!read input error!!!\n");
-                       continue;
+               err = camera_create(CAMERA_DEVICE_CAMERA0, &hcamcorder->camera);
+               if (err != CAMERA_ERROR_NONE) {
+                       g_print("camera create failed 0x%d\n", err);
+                       return FALSE;
                }
 
-               LOGD("media type : %c", media_type);
-
-               switch (media_type) {
-               case '1':
-                       hcamcorder->mode = MODE_VIDEO_CAPTURE;
-
-                       LOGD("camera_create");
-
-                       err = camera_create(CAMERA_DEVICE_CAMERA0, &hcamcorder->camera);
-                       if (err != CAMERA_ERROR_NONE) {
-                               LOGE("camera create failed 0x%d", err);
-                               continue;
-                       }
-
-                       err = camera_set_display(hcamcorder->camera, CAMERA_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(display));
-                       if (err != CAMERA_ERROR_NONE) {
-                               LOGE("set display failed 0x%d", err);
-                               camera_destroy(hcamcorder->camera);
-                               hcamcorder->camera = NULL;
-                               continue;
-                       }
-
-                       err = camera_start_preview(hcamcorder->camera);
-                       if (err != CAMERA_ERROR_NONE) {
-                               LOGE("start preview failed 0x%d", err);
-                               camera_destroy(hcamcorder->camera);
-                               hcamcorder->camera = NULL;
-                               continue;
-                       }
-
-                       err = recorder_create_videorecorder(hcamcorder->camera, &hcamcorder->recorder);
-                       if (err != RECORDER_ERROR_NONE) {
-                               LOGE("video recorder create failed 0x%d", err);
-                               camera_stop_preview(hcamcorder->camera);
-                               camera_destroy(hcamcorder->camera);
-                               hcamcorder->camera = NULL;
-                               continue;
-                       }
+               err = camera_set_display(hcamcorder->camera, CAMERA_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(ad.win));
+               if (err != CAMERA_ERROR_NONE) {
+                       g_print("set display failed 0x%d\n", err);
+                       camera_destroy(hcamcorder->camera);
+                       hcamcorder->camera = NULL;
+                       return FALSE;
+               }
 
-                       check = TRUE;
-                       break;
-               case '2':
-                       hcamcorder->mode = MODE_AUDIO;
-                       err = recorder_create_audiorecorder(&hcamcorder->recorder);
-                       if (err != RECORDER_ERROR_NONE) {
-                               LOGE("audio recorder create failed 0x%x", err);
-                               continue;
-                       }
+               err = camera_start_preview(hcamcorder->camera);
+               if (err != CAMERA_ERROR_NONE) {
+                       g_print("start preview failed 0x%d\n", err);
+                       camera_destroy(hcamcorder->camera);
+                       hcamcorder->camera = NULL;
+                       return FALSE;
+               }
 
-                       {
-                               sound_stream_info_h stream_info = NULL;
+               err = recorder_create_videorecorder(hcamcorder->camera, &hcamcorder->recorder);
+               if (err != RECORDER_ERROR_NONE) {
+                       g_print("video recorder create failed 0x%d\n", err);
+                       camera_stop_preview(hcamcorder->camera);
+                       camera_destroy(hcamcorder->camera);
+                       hcamcorder->camera = NULL;
+                       return FALSE;
+               }
 
-                               sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _sound_stream_focus_state_changed_cb, hcamcorder, &stream_info);
-                               if (stream_info) {
-                                       recorder_set_sound_stream_info(hcamcorder->recorder, stream_info);
-                                       sound_manager_destroy_stream_information(stream_info);
-                               }
-                       }
+               check = TRUE;
+               break;
+       case '2':
+               hcamcorder->mode = MODE_AUDIO;
+               err = recorder_create_audiorecorder(&hcamcorder->recorder);
+               if (err != RECORDER_ERROR_NONE) {
+                       g_print("audio recorder create failed 0x%x\n", err);
+                       return FALSE;
+               }
 
-                       err = recorder_attr_set_audio_device(hcamcorder->recorder, RECORDER_AUDIO_DEVICE_MIC);
-                       if (err != RECORDER_ERROR_NONE) {
-                               LOGE("set audio device failed 0x%x", err);
-                               recorder_destroy(hcamcorder->recorder);
-                               hcamcorder->recorder = NULL;
-                               continue;
-                       }
+               {
+                       sound_stream_info_h stream_info = NULL;
 
-                       check = TRUE;
-                       break;
-               case '3':
-                       hcamcorder->mode = MODE_AUDIO;
-                       err = recorder_create_audiorecorder(&hcamcorder->recorder);
-                       if (err != RECORDER_ERROR_NONE) {
-                               LOGE("audio recorder create failed 0x%d", err);
-                               continue;
+                       sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _sound_stream_focus_state_changed_cb, hcamcorder, &stream_info);
+                       if (stream_info) {
+                               recorder_set_sound_stream_info(hcamcorder->recorder, stream_info);
+                               sound_manager_destroy_stream_information(stream_info);
                        }
+               }
 
-                       recorder_attr_set_audio_device(hcamcorder->recorder, RECORDER_AUDIO_DEVICE_MODEM);
-                       if (err != RECORDER_ERROR_NONE) {
-                               LOGE("set audio device failed 0x%d", err);
-                               recorder_destroy(hcamcorder->recorder);
-                               hcamcorder->recorder = NULL;
-                               continue;
-                       }
+               err = recorder_attr_set_audio_device(hcamcorder->recorder, RECORDER_AUDIO_DEVICE_MIC);
+               if (err != RECORDER_ERROR_NONE) {
+                       g_print("set audio device failed 0x%x\n", err);
+                       recorder_destroy(hcamcorder->recorder);
+                       hcamcorder->recorder = NULL;
+                       return FALSE;
+               }
 
-                       check = TRUE;
-                       break;
-               case 'q':
-                       g_print("\t Quit Camcorder Testsuite!!\n");
-                       hcamcorder->mode = -1;
-                       if (g_main_loop_is_running(g_loop))
-                               g_main_loop_quit(g_loop);
+               check = TRUE;
+               break;
+       case '3':
+               hcamcorder->mode = MODE_AUDIO;
+               err = recorder_create_audiorecorder(&hcamcorder->recorder);
+               if (err != RECORDER_ERROR_NONE) {
+                       g_print("audio recorder create failed 0x%d\n", err);
+                       return FALSE;
+               }
 
+               err = recorder_attr_set_audio_device(hcamcorder->recorder, RECORDER_AUDIO_DEVICE_MODEM);
+               if (err != RECORDER_ERROR_NONE) {
+                       g_print("set audio device failed 0x%d\n", err);
+                       recorder_destroy(hcamcorder->recorder);
+                       hcamcorder->recorder = NULL;
                        return FALSE;
-               default:
-                       g_print("\t Invalid media type(%c)\n", media_type);
-                       continue;
                }
-       }
 
-       g_timer_reset(timer);
+               check = TRUE;
+               break;
+       case '4':
+               err = recorder_add_device_state_changed_cb(_recorder_device_state_changed_cb,
+                       NULL, &g_recorder_device_changed_cb_id);
+               g_print("add result 0x%x - cb id %d\n", err, g_recorder_device_changed_cb_id);
+               return FALSE;
+       case '5':
+               if (g_recorder_device_changed_cb_id > 0) {
+                       err = recorder_remove_device_state_changed_cb(g_recorder_device_changed_cb_id);
+                       g_recorder_device_changed_cb_id = 0;
+                       g_print("remove result 0x%x\n", err);
+               } else {
+                       g_print("invalid callback id %d\n", g_recorder_device_changed_cb_id);
+               }
+               return FALSE;
+       case '6':
+               err = recorder_get_device_state(RECORDER_TYPE_AUDIO, &device_state);
+               g_print("get result 0x%x - audio state %d\n", err, device_state);
+               err = recorder_get_device_state(RECORDER_TYPE_VIDEO, &device_state);
+               g_print("get result 0x%x - video state %d\n", err, device_state);
+               return FALSE;
+       case 'q':
+               g_print("\t Quit Camcorder Testsuite!!\n");
+               hcamcorder->mode = -1;
+               elm_exit();
+               return FALSE;
+       default:
+               g_print("\t Invalid media type(%c)\n", media_type);
+               return FALSE;
+       }
 
        if (!init(hcamcorder->mode)) {
-               LOGE("testsuite init() failed.");
-               return -1;
+               g_print("testsuite init() failed.\n");
+               return FALSE;
        }
 
-       g_timer_reset(timer);
-
        err = recorder_prepare(hcamcorder->recorder);
 
-       LOGD("recorder_start()  : %12.6lfs", g_timer_elapsed(timer, NULL));
+       g_print("recorder_prepare()  : %12.6lfs\n", g_timer_elapsed(timer, NULL));
 
        if (err != RECORDER_ERROR_NONE) {
-               LOGE("recorder_start  = %x", err);
-               return -1;
+               g_print("recorder_prepare  = %x\n", err);
+               return FALSE;
        }
 
        g_get_current_time(&current);
        timersub(&current, &previous, &res);
 
-       LOGD("Recorder Starting Time  : %ld.%lds", res.tv_sec, res.tv_usec);
+       g_print("Recorder Preparing Time  : %ld.%lds\n", res.tv_sec, res.tv_usec);
+
+       hcamcorder->menu_state = MENU_STATE_MAIN;
 
        return TRUE;
 }
 
 
-/**
- * This function is the example main function for recorder API.
- *
- * @param
- *
- * @return   This function returns 0.
- * @remark
- * @see      other functions
- */
-int main(int argc, char **argv)
+static int app_create(void *data)
 {
-       int bret;
+       appdata *app_data = data;
+       int w = 0;
+       int h = 0;
+       Evas_Object *win = NULL;
+       Evas_Object *eo = NULL;
+       Evas_Object *bg = NULL;
+       Evas_Object *rect = NULL;
 
-#if !GLIB_CHECK_VERSION(2, 35, 0)
-       if (!g_thread_supported())
-               g_thread_init(NULL);
-#endif
+       if (app_data == NULL) {
+               g_print("\t\nappdata is NULL\n");
+               return 0;
+       }
 
-       timer = g_timer_new();
+       /* use gl backend */
+       elm_config_accel_preference_set("opengl");
+
+       win = elm_win_add(NULL, "camera_test", ELM_WIN_BASIC);
+       if (win) {
+               elm_win_title_set(win, "camera_test");
+               elm_win_borderless_set(win, EINA_TRUE);
+               elm_win_screen_size_get(win, NULL, NULL, &w, &h);
+               g_print("\n\tscreen size %dx%d\n\n", w, h);
+               evas_object_resize(win, w, h);
+               elm_win_autodel_set(win, EINA_TRUE);
+               elm_win_alpha_set(win, EINA_TRUE);
+       } else {
+               g_print("\n\tfailed to get window\n\n");
+               return 1;
+       }
 
-       elm_init(argc, argv);
+       bg = elm_bg_add(win);
+       if (bg) {
+               elm_win_resize_object_add(win, bg);
+               evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               evas_object_show(bg);
+       } else {
+               g_print("\n\tfailed to get elm bg\n\n");
+               return 1;
+       }
 
-       LOGD("elm_init() : %12.6lfs", g_timer_elapsed(timer, NULL));
+       rect = evas_object_rectangle_add(evas_object_evas_get(win));
+       if (rect) {
+               evas_object_color_set(rect, 0, 0, 0, 0);
+               evas_object_render_op_set(rect, EVAS_RENDER_COPY);
+       } else {
+               g_print("\n\tfailed to get rectangle\n\n");
+               return 1;
+       }
 
-       hcamcorder = (cam_handle_t *) g_malloc0(sizeof(cam_handle_t));
+       elm_win_resize_object_add(win, rect);
+       evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       evas_object_show(rect);
 
-       Evas_Object *eo = NULL;
-       eo = elm_win_add(NULL, "VIDEO OVERLAY", ELM_WIN_BASIC);
-       elm_win_title_set(eo, "VIDEO oVERLAY");
-       evas_object_resize(eo, 200, 200);
+       /* Create evas image object for EVAS surface */
+       eo = evas_object_image_add(evas_object_evas_get(win));
+       evas_object_image_size_set(eo, w, h);
+       evas_object_image_fill_set(eo, 0, 0, w, h);
+       evas_object_resize(eo, w, h);
        evas_object_show(eo);
-       display = (void *)eo;
 
-       recorder_state = RECORDER_STATE_NONE;
+       elm_win_activate(win);
+       evas_object_show(win);
 
+       app_data->win = win;
+       app_data->eo = eo;
+
+       timer = g_timer_new();
        g_timer_reset(timer);
 
-       bret = mode_change();
-       if (!bret)
-               return bret;
+       init_handle();
 
        print_menu();
 
-       g_loop = g_main_loop_new(NULL, FALSE);
-
-       stdin_channel = g_io_channel_unix_new(fileno(stdin));/* read from stdin */
-       g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)cmd_input, NULL);
-
-       LOGD("RUN main loop");
+       return 0;
+}
 
-       g_main_loop_run(g_loop);
+static int app_terminate(void *data)
+{
+       appdata *app_data = data;
 
-       LOGD("STOP main loop");
+       if (app_data == NULL) {
+               g_print("\n\tappdata is NULL\n");
+               return 0;
+       }
 
        if (timer) {
                g_timer_stop(timer);
                g_timer_destroy(timer);
                timer = NULL;
        }
-       /* g_print("\t Exit from the application.\n"); */
+
+       return 0;
+}
+
+
+/**
+ * This function is the example main function for mmcamcorder API.
+ *
+ * @param
+ *
+ * @return  This function returns 0.
+ * @remark
+ * @see     other functions
+ */
+int main(int argc, char **argv)
+{
+       int bret;
+
+       hcamcorder = (cam_handle_t *)g_malloc0(sizeof(cam_handle_t));
+       recorder_state = RECORDER_STATE_NONE;
+
+       stdin_channel = g_io_channel_unix_new(fileno(stdin));/* read from stdin */
+       g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)cmd_input, NULL);
+
+       memset(&ad, 0x0, sizeof(appdata));
+       ops.data = &ad;
+
+       bret = appcore_efl_main(PACKAGE, &argc, &argv, &ops);
+
+       g_print("\n\treturn appcore_efl : %d\n\n", bret);
+
        g_free(hcamcorder);
-       g_main_loop_unref(g_loop);
        g_io_channel_unref(stdin_channel);
 
        return bret;
 }
-
 /*EOF*/