diff options
Diffstat (limited to 'src/camera.c')
-rw-r--r-- | src/camera.c | 486 |
1 files changed, 381 insertions, 105 deletions
diff --git a/src/camera.c b/src/camera.c index b71ac92..78bf839 100644 --- a/src/camera.c +++ b/src/camera.c @@ -37,12 +37,19 @@ #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; +} |