diff options
Diffstat (limited to 'src/cam.c')
-rwxr-xr-x | src/cam.c | 924 |
1 files changed, 924 insertions, 0 deletions
diff --git a/src/cam.c b/src/cam.c new file mode 100755 index 0000000..cbbea46 --- /dev/null +++ b/src/cam.c @@ -0,0 +1,924 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#ifndef UG_MODULE_API +#define UG_MODULE_API __attribute__ ((visibility("default"))) +#endif + + +#include <stdio.h> +#include <pthread.h> +#include <X11/Xlib.h> +#include <utilX.h> +#include <power.h> +#include <ui-gadget-module.h> +#include "cam.h" +#include "cam_app.h" +#include "camera_utils.h" +#include "cam_ta.h" +#include "cam_mm.h" +#include "cam_debug.h" +#include "cam_toolbar_edc_callback.h" +#include "cam_zoom_edc_callback.h" +#include "cam_indicator_edc_callback.h" +#include "cam_common_edc_callback.h" +#include "cam_rec.h" +#include "cam_file.h" +#include "cam_menu_composer.h" +#include "cam_device_capacity.h" + + +#define CAM_EXT_LIB_PATH "/usr/lib/libcamera-external-engine.so" + +void *handle = NULL; + + +static Evas_Object *__create_base_layout(Evas_Object *parent); +static void __low_battery_cb(void *data); +static gboolean __device_orientation_cb(app_device_orientation_e mode, void *data); +static int __is_idle_lock(void); +static Eina_Bool __resume_camera(void* data); +static int __convert_orientation_to_angle(app_device_orientation_e orientation); +void *__cam_start_thread_run(void *data); +static void __accelerometer_cb(unsigned long long timestamp, sensor_data_accuracy_e accuracy, float x, float y, float z, void *user_data); +static gboolean __start_sensor(void* data); + + +static void *on_create(ui_gadget_h ug, enum ug_mode mode, service_h service, void *priv) +{ + CAM_TA_ACUM_ITEM_BEGIN("==on_create==", 0); + cam_debug(LOG_UI, "############## on_create START ##############"); + + cam_retvm_if(ug == NULL, NULL, "ui_gadget_h is NULL"); + struct appdata *ad = (struct appdata *)priv; + cam_retvm_if(ad == NULL, NULL, "appdata is NULL"); + Ecore_X_Display *dpy = NULL; + + bindtextdomain(PACKAGE, "/usr/ug/res/locale"); + + ad->camera_ug = ug; + + /* get parent's layout */ + ad->win_main = ug_get_window(); + cam_retvm_if(ad->win_main == NULL, NULL, "ug_get_window failed"); + + /* create base layout */ + ad->ug_base = __create_base_layout(ad->win_main); + cam_retvm_if(ad->ug_base == NULL, NULL, "__create_base_layout failed"); + + /* Camera does not support desktop mode */ + const char *str = "mobile"; + elm_win_profiles_set(ad->win_main, &str, 1); + + /* remove effect */ + dpy = ecore_x_display_get(); + if (dpy) { + Ecore_X_Window win; + win = elm_win_xwindow_get(ad->win_main); + + cam_debug(LOG_UI, "dpy is not null .. set no effect to display = %d\n", win); + utilx_set_window_effect_style(dpy, win, + UTILX_EFFECT_TYPE_ROTATION, + UTILX_EFFECT_STYLE_NONE); + } + + ad->evas = evas_object_evas_get(ad->win_main); + ad->ee = ecore_evas_ecore_evas_get(ad->evas); + ad->main_xid = elm_win_xwindow_get(ad->win_main); + + /* camera application initialization */ + CAM_TA_ACUM_ITEM_BEGIN(" cam_app_init", 0); + if (!cam_app_init(ad)) { + cam_critical(LOG_UI, "cam_app_init failed"); + return NULL; + } + CAM_TA_ACUM_ITEM_END(" cam_app_init", 0); + + /*add camera exteral engine lib load*/ + if (!open_cam_ext_handle()) { + cam_critical(LOG_UI, "open_cam_ext_handle failed"); + } + + ad->rot_current = app_get_device_orientation(); + ad->rot_previous = ad->rot_current; + int win_angle = elm_win_rotation_get(ad->win_main); + ad->angle = __convert_orientation_to_angle(ad->rot_current); + + if(win_angle != ad->angle) { + cam_critical(LOG_UI, "win_angle:%d device_angle:%d ", win_angle, ad->angle); + elm_win_rotation_with_resize_set(ad->win_main, ad->angle); + } + + evas_object_show(ad->win_main); + + if (!cam_check_dir()) { + cam_app_notice_popup(ad, "Cannot make default path", cam_app_timeout_notice_response_cb); + return NULL; + } + + if (!cam_utils_check_torchlight_status(ad)) { + DEBUG_TRACE("Can not get torchlight status"); + } + + /* remove exe args */ + if (ad->exe_args) { + if (ad->exe_args->caller) { + free(ad->exe_args->caller); + ad->exe_args->caller = NULL; + } + free(ad->exe_args); + ad->exe_args = NULL; + } + + char *operation = NULL; + int ret = service_get_operation(service, &operation); + if (ret != SERVICE_ERROR_NONE) { + cam_critical(LOG_UI, "service_get_operation failed"); + return NULL; + } + + if (operation == NULL) { + cam_critical(LOG_UI, "operation is null"); + return NULL; + } + + if (strcmp(operation, SERVICE_OPERATION_CREATE_CONTENT) == 0) { + cam_debug(LOG_UI, "Operation is SERVICE_OPERATION_CREATE_CONTENT"); + + ad->launching_mode = CAM_LAUNCHING_MODE_EXTERNAL; + + ret = service_clone(&ad->service_handle, service); + if (ret != SERVICE_ERROR_NONE) { + cam_critical(LOG_UI, "service_clone failed"); + return NULL; + } + + CamExeArgs *args = (CamExeArgs *)malloc(sizeof(CamExeArgs)); + if (args == NULL) { + cam_critical(LOG_UI, "Memory allocation failed"); + return NULL; + } + memset(args, 0, sizeof(CamExeArgs)); + + if (!cam_app_parse_args(args, service)) { + cam_critical(LOG_UI, "cam_app_parse_args failed"); + if (args) { + if (args->caller) { + free(args->caller); + args->caller = NULL; + } + free(args); + args = NULL; + } + return NULL; + } + ad->exe_args = args; + + if (!cam_mm_create(CAM_DEVICE_MEGA, ad->exe_args->cam_mode)) { + cam_critical(LOG_MM, "cam_mm_create failed"); + ad->error_type = CAM_ERROR_TYPE_UNABLE_TO_LAUNCH; + return NULL; + } + + CAM_TA_ACUM_ITEM_BEGIN(" cam_handle_init", 0); + if (!cam_handle_init(ad, ad->exe_args->cam_mode)) { + cam_critical(LOG_CAM, "cam_handle_init failed"); + return NULL; + } + CAM_TA_ACUM_ITEM_END(" cam_handle_init", 0); + + cam_app_init_with_args(ad); + } else { + ad->launching_mode = CAM_LAUNCHING_MODE_NORMAL; + + if (!cam_mm_create(CAM_DEVICE_MEGA, CAM_CAMERA_MODE)) { + cam_critical(LOG_MM, "cam_mm_create failed"); + ad->error_type = CAM_ERROR_TYPE_UNABLE_TO_LAUNCH; + return NULL; + } + + CAM_TA_ACUM_ITEM_BEGIN(" cam_handle_init", 0); + if (!cam_handle_init(ad, CAM_CAMERA_MODE)) { + cam_critical(LOG_CAM, "cam_handle_init failed"); + return NULL; + } + CAM_TA_ACUM_ITEM_END(" cam_handle_init", 0); + } + + ad->error_type = CAM_ERROR_TYPE_NONE; + + if (cam_utils_check_battery_critical_low()) { + ad->battery_status = LOW_BATTERY_CRITICAL_STATUS; + } else if (cam_utils_check_battery_warning_low()) { + ad->battery_status = LOW_BATTERY_WARNING_STATUS; + } else { + ad->battery_status = NORMAL_BATTERY_STATUS; + } + + if (cam_utils_check_call_running()) + ad->is_calling = TRUE; + else + ad->is_calling = FALSE; + + if ( ad->battery_status != LOW_BATTERY_CRITICAL_STATUS + || ad->is_calling == FALSE) { + if (pthread_create(&(ad->camera_start_thread), NULL, __cam_start_thread_run, (void *)ad) < 0) { + cam_critical(LOG_CAM, "Create camera start thread failed"); + return NULL; + } + } + + cam_debug(LOG_UI, "############## on_create END ##############"); + CAM_TA_ACUM_ITEM_END("==on_create==", 0); + + return ad->ug_base; +} + +static void on_start(ui_gadget_h ug, service_h service, void *priv) +{ + CAM_TA_ACUM_ITEM_BEGIN("==on_start==", 0); + cam_debug(LOG_UI, "############## on_start START ##############"); + + cam_retm_if(ug == NULL, "ui_gadget_h is NULL"); + struct appdata *ad = (struct appdata *)priv; + cam_retm_if(ad == NULL, "appdata is NULL"); + CamAppData *camapp = ad->camapp_handle; + cam_retm_if(camapp == NULL, "camapp_handle is NULL"); + + ad->ug_state = CAM_UG_RESET_STATE; + +#ifdef EFL_TEMP_CODE + cam_win_transparent_set(ad); +#endif + + cam_app_get_win_size(ad); + + power_lock_state(POWER_STATE_NORMAL, 0); + + /*elm_win_alpha_set(ad->win_main, EINA_TRUE);*/ + + ad->setting_menu_composer = NULL; + + if( ad->setting_menu_composer == NULL){ + ad->setting_menu_composer = calloc(1, sizeof(cam_menu_composer)); + cam_compose_setting_menu((void*)ad, ad->setting_menu_composer); + } + + CAM_TA_ACUM_ITEM_BEGIN(" cam_layout_init", 0); + if (!cam_layout_init(ad)) { + cam_critical(LOG_UI, "cam_layout_init failed"); + return; + } + CAM_TA_ACUM_ITEM_END(" cam_layout_init", 0); + + __start_sensor(ad); + + cam_debug(LOG_UI, "############## on_start END##############"); + CAM_TA_ACUM_ITEM_END("==cam_service==", 0); +} + +static void on_pause(ui_gadget_h ug, service_h service, void *priv) +{ + CAM_TA_ACUM_ITEM_BEGIN("==on_pause==", 0); + cam_debug(LOG_UI, "############## on_pause ##############"); + + cam_retm_if(ug == NULL, "ui_gadget_h is NULL"); + struct appdata *ad = (struct appdata *)priv; + cam_retm_if(ad == NULL, "appdata is NULL"); + CamAppData *camapp = ad->camapp_handle; + cam_retm_if(camapp == NULL, "camapp_handle is NULL"); + + ad->ug_state = CAM_UG_PAUSE_STATE; + + int ret = -1; + ret = sensor_stop(ad->sensor, SENSOR_ACCELEROMETER); + if(ret != SENSOR_ERROR_NONE){ + cam_critical(LOG_MM, "sensor_stop fail %d", ret); + return; + } + + if (ad->location_ug) { + ug_destroy(ad->location_ug); + ad->location_ug = NULL; + } + + if (ad->imageviewer_ug) { + DEBUG_TRACE("imageviewer_ug exist"); + return; + } + + CAM_TA_ACUM_ITEM_BEGIN(" app_stop", 0); + DEBUG_TRACE(" "); + + cam_app_pause(ad); + + power_unlock_state(POWER_STATE_NORMAL); + CAM_TA_ACUM_ITEM_END(" app_stop", 0); + + CAM_TA_ACUM_ITEM_END("==on_pause==", 0); +} + +static void on_resume(ui_gadget_h ug, service_h service, void *priv) +{ + CAM_TA_ACUM_ITEM_BEGIN("==on_resume==", 0); + cam_debug(LOG_UI, "############## on_resume ##############"); + + cam_retm_if(ug == NULL, "ui_gadget_h is NULL"); + struct appdata *ad = (struct appdata *)priv; + cam_retm_if(ad == NULL, "appdata is NULL"); + CamAppData *camapp = ad->camapp_handle; + cam_retm_if(camapp == NULL, "camapp_handle is NULL"); + + ad->ug_state = CAM_UG_RESUME_STATE; + + evas_object_raise(ad->win_main); + + if (!cam_check_dir()) { + cam_app_notice_popup(ad, "Cannot make default path", + cam_app_timeout_notice_response_cb); + return; + } + + int ret = -1; + ret = sensor_start(ad->sensor, SENSOR_ACCELEROMETER); + if(ret != SENSOR_ERROR_NONE){ + cam_critical(LOG_MM, "sensor_start fail %d ", ret); + return; + } + + cam_mm_set_display_visible(TRUE); + + if (!cam_utils_check_torchlight_status(ad)) { + DEBUG_TRACE("Can not get torchlight status"); + } + + app_device_orientation_e rot_current = app_get_device_orientation(); + DEBUG_TRACE("rot_current:%d, ad->rot_current:%d, ad->angle:%d", rot_current, ad->rot_current, ad->angle); + if (rot_current != ad->rot_current) { + ecore_idler_add(__resume_camera, ad); + } + + if (ad->imageviewer_ug) { /* bug fix camera app overlab with imageviewer_ug */ + DEBUG_TRACE("imageviewer_ug exist"); + return; + } + + power_lock_state(POWER_STATE_NORMAL, 0); + + CAM_TA_INIT(); + + if (ad) { + CAM_TA_ACUM_ITEM_BEGIN(" cam_app_resume", 0); + if (!cam_app_resume(ad)) + return; + CAM_TA_ACUM_ITEM_END(" cam_app_resume", 0); + } + + CAM_TA_ACUM_ITEM_END("==on_resume==", 0); +} + +static void on_destroy(ui_gadget_h ug, service_h service, void *priv) +{ + CAM_TA_ACUM_ITEM_BEGIN("==on_destroy==", 0); + cam_debug(LOG_UI, "############## on_destroy ##############"); + + cam_retm_if(ug == NULL, "ui_gadget_h is NULL"); + struct appdata *ad = (struct appdata *)priv; + cam_retm_if(ad == NULL, "appdata is NULL"); + + ad->ug_state = CAM_UG_TERMINATE_STATE; + + sensor_accelerometer_unset_cb(ad->sensor); + if(sensor_stop(ad->sensor, SENSOR_ACCELEROMETER) == SENSOR_ERROR_NONE) + sensor_destroy(ad->sensor); + + if (ad->camera_start_thread) { + pthread_join(ad->camera_start_thread, NULL); + } + +#ifdef USE_FIFO_THREAD + cam_app_FIFO_thread_exit(); +#endif + + cam_app_file_register_thread_exit(ad); + + cam_continuous_shot_file_save_thread_exit(ad); + CAM_TA_ACUM_ITEM_BEGIN(" cam_app_stop", 0); + cam_app_stop(ad); + CAM_TA_ACUM_ITEM_END(" cam_app_stop", 0); + + power_unlock_state(POWER_STATE_NORMAL); + + CAM_TA_ACUM_ITEM_SHOW_RESULT_TO(CAM_TA_SHOW_FILE); + CAM_TA_RELEASE(); + + close_cam_ext_handle(); + + CAM_TA_ACUM_ITEM_END("==on_destroy==", 0); +} + +static void on_message(ui_gadget_h ug, service_h msg, service_h service, void *priv) +{ + cam_critical(LOG_UI, "############## on_message ##############"); + + cam_retm_if(ug == NULL, "ui_gadget_h is NULL"); + struct appdata *ad = (struct appdata *)priv; + cam_retm_if(ad == NULL, "appdata is NULL"); + + /* Check service for DFT mmi-check */ + if ((ad->ug_state == CAM_UG_RESUME_STATE) || (ad->ug_state == CAM_UG_RESET_STATE)) { + char *mmi_check = NULL; + service_get_extra_data(service, "MMICHECK_CAMERA", (char **)&mmi_check); + if (mmi_check) { + cam_critical(LOG_UI, "MMICHECK_CAMERA %s", mmi_check); + if (0 == strcmp(mmi_check, "1")) { + if (!cam_do_capture(ad)) { + cam_critical(LOG_UI, "cam_do_capture failed"); + } + } + } else { + cam_critical(LOG_UI, "not mmi check case, error!"); + } + } +} + +static void on_event(ui_gadget_h ug, enum ug_event event, service_h service, void *priv) +{ + cam_critical(LOG_UI, "############## on_event ##############"); + + cam_retm_if(ug == NULL, "ui_gadget_h is NULL"); + struct appdata *ad = (struct appdata *)priv; + cam_retm_if(ad == NULL, "appdata is NULL"); + + switch (event) { + case UG_EVENT_LOW_BATTERY: + __low_battery_cb(ad); + break; + case UG_EVENT_LANG_CHANGE: + case UG_EVENT_ROTATE_PORTRAIT: + case UG_EVENT_ROTATE_LANDSCAPE: + case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN: + case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN: + case UG_EVENT_LOW_MEMORY: + case UG_EVENT_REGION_CHANGE: + default: + DEBUG_TRACE("Ignore Event - [%d]", event); + break; + } +} + +gboolean open_cam_ext_handle() +{ + if (!handle) { + /*NOTE: RTLD_LAZY: it will check dynamic lib api while use it, + RTLD_NOW: it will check each api before open dynamic lib*/ + handle = dlopen(CAM_EXT_LIB_PATH, RTLD_LAZY); + if ( !handle ) { + char *msg = NULL; + msg = strdup(dlerror()); + DEBUG_TRACE("error: %s", msg); + return FALSE; + } + } + return TRUE; +} + +void close_cam_ext_handle() +{ + if (handle) { + dlclose(handle); + handle = NULL; + } +} + +static Evas_Object *__create_base_layout(Evas_Object *parent) +{ + Evas_Object *base; + int r = 0; + + base = elm_layout_add(parent); + cam_retvm_if(base == NULL, NULL, "elm_layout_add failed"); + + r = elm_layout_file_set(base, CAM_MAIN_LAYOUT_EDJ_NAME, "main_layout"); + if (!r) { + evas_object_del(base); + return NULL; + } + + evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(base); + + return base; +} + +static void __low_battery_cb(void *data) +{ + cam_info(LOG_SYS, "Low battery !!"); + + struct appdata *ad = (struct appdata *)data; + cam_retm_if(ad == NULL, "appdata is NULL"); + CamAppData *camapp = ad->camapp_handle; + cam_retm_if(camapp == NULL, "camapp_handle is NULL"); + + if (evas_object_visible_get(ad->win_main)) { + int state = cam_mm_get_state(); + if ((state == RECORDER_STATE_RECORDING + || state == RECORDER_STATE_PAUSED) + &&camapp->camera_mode == CAM_CAMCORDER_MODE) { + camapp->rec_stop_type = CAM_REC_STOP_LOW_BATTERY; + ad->recording_commit = + ecore_idler_add(cam_video_idler_record_stop, ad); + } else { + cam_app_exit(ad); + } + } +} + +static gboolean __device_orientation_cb(app_device_orientation_e mode, void *data) +{ + cam_debug(LOG_UI, "############## cam_device_orientation_cb ##############"); + + struct appdata *ad = (struct appdata *)data; + cam_retvm_if(ad == NULL, FALSE, "appdata is NULL"); + cam_retvm_if(ad->camapp_handle == NULL, FALSE, "ad->camapp_handle is NULL"); + + if(ad->camapp_handle->continuous_shot_data && + ad->camapp_handle->continuous_shot_data->capture_status == CAM_CONTI_SHOT_STATUS_CAPTURING){ + cam_debug(LOG_UI, "capturing"); + return FALSE; + } + if (ad->bestshot_thumbnails_edje) { + cam_debug(LOG_UI, "is creating best shot thumbnails"); + return FALSE; + } + cam_debug(LOG_UI, "rotated : %d", mode); + + /*TODO: now just return, if the last rotated is not finished*/ + if (ad->is_rotating) { + cam_debug(LOG_UI, "rotating..."); + return FALSE; + } + + int angle = 0; + ui_gadget_h ug = NULL; + + enum ug_event ev = UG_EVENT_ROTATE_LANDSCAPE; + ad->rot_previous = ad->rot_current; + ad->rot_current = mode; + + if (ad->toolbar_edj_file) + free(ad->toolbar_edj_file); + ad->toolbar_edj_file = NULL; + + switch (mode) { + case APP_DEVICE_ORIENTATION_0: + angle = 0; + ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT; + ev = UG_EVENT_ROTATE_PORTRAIT; + ad->camcorder_rotate = CAMERA_ROTATION_90; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_EDJ_NAME); + break; + case APP_DEVICE_ORIENTATION_270: + angle = 270; + ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE; + ev = UG_EVENT_ROTATE_LANDSCAPE; + ad->camcorder_rotate = CAMERA_ROTATION_NONE; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_EDJ_NAME); + break; + case APP_DEVICE_ORIENTATION_180: + angle = 180; + ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT_INVERSE; + ev = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN; + ad->camcorder_rotate = CAMERA_ROTATION_270; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_INVERSE_EDJ_NAME); + break; + case APP_DEVICE_ORIENTATION_90: + angle = 90; + ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE_INVERSE; + ev = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN; + ad->camcorder_rotate = CAMERA_ROTATION_180; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_INVERSE_EDJ_NAME); + break; + + default: + break; + } + ad->angle = angle; + + if (ad->imageviewer_ug) { + ug = ad->imageviewer_ug; + } else if (ad->location_ug) { + ug = ad->location_ug; + } + if (ug) { + enum ug_mode md = ug_get_mode(ug); + if (md == UG_MODE_FULLVIEW) { + + int rotate = 0; + int ret = -1; + + ret = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &rotate); + if (ret != 0) { + return FALSE; + } + + if (rotate == 0) { + cam_critical(LOG_UI, "Rotation is lock"); + return FALSE; + } + + elm_win_rotation_with_resize_set(ad->win_main, angle); + /* send event to ug */ + ug_send_event(ev); + } + } else { + + cam_utils_request_main_pipe_handler(ad, NULL, CAM_MAIN_PIPE_OP_TYPE_ROTATE_ANIMATOR); + } + + return TRUE; +} + +static int __is_idle_lock(void) +{ + int vconf_val = 0; + int vconf_ret = 0; + + vconf_ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &vconf_val); + if(vconf_ret == 0){ + if (vconf_val == VCONFKEY_IDLE_LOCK) { + DEBUG_TRACE(" IDLE IN LOCK STATE "); + return 1; + } + } + + return 0; +} + +static Eina_Bool __resume_camera(void *data) +{ + struct appdata *ad = data; + cam_retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "appdata is NULL"); + + ad->rot_current = app_get_device_orientation(); + ad->rot_previous = ad->rot_current; + int angle = 0; + ui_gadget_h ug = NULL; + enum ug_event ev = UG_EVENT_ROTATE_LANDSCAPE; + switch (ad->rot_current) { + case APP_DEVICE_ORIENTATION_0: + angle = 0; + ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT; + ev = UG_EVENT_ROTATE_PORTRAIT; + ad->camcorder_rotate = CAMERA_ROTATION_90; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_EDJ_NAME); + break; + case APP_DEVICE_ORIENTATION_270: + angle = 270; + ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE; + ev = UG_EVENT_ROTATE_LANDSCAPE; + ad->camcorder_rotate = CAMERA_ROTATION_NONE; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_EDJ_NAME); + break; + case APP_DEVICE_ORIENTATION_180: + angle = 180; + ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT_INVERSE; + ev = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN; + ad->camcorder_rotate = CAMERA_ROTATION_270; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_INVERSE_EDJ_NAME); + break; + case APP_DEVICE_ORIENTATION_90: + angle = 90; + ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE_INVERSE; + ev = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN; + ad->camcorder_rotate = CAMERA_ROTATION_180; + ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_INVERSE_EDJ_NAME); + break; + + default: + break; + } + ad->angle = angle; + if (ad->imageviewer_ug) { + ug = ad->imageviewer_ug; + } else if (ad->location_ug) { + ug = ad->location_ug; + } + if (ug) { + enum ug_mode md = ug_get_mode(ug); + if (md == UG_MODE_FULLVIEW) { + elm_win_rotation_with_resize_set(ad->win_main, ad->angle); + /* send event to ug */ + ug_send_event(ev); + } + } else { + cam_utils_request_main_pipe_handler(ad, NULL, CAM_MAIN_PIPE_OP_TYPE_ROTATE_ANIMATOR); + } + return ECORE_CALLBACK_CANCEL; + +} + +static int __convert_orientation_to_angle(app_device_orientation_e orientation) +{ + + switch (orientation) { + case APP_DEVICE_ORIENTATION_0: + return 0; + break; + case APP_DEVICE_ORIENTATION_180: + return 180; + break; + case APP_DEVICE_ORIENTATION_270: + return 270; + break; + case APP_DEVICE_ORIENTATION_90: + return 90; + break; + default: + return 0; + } +} + +void *__cam_start_thread_run(void *data) +{ + struct appdata *ad = (struct appdata *)data; + cam_retv_if(ad == NULL, NULL); + + if(cam_mm_is_created()){ + if (!cam_app_start(ad)){ + cam_critical(LOG_CAM, "cam_app_start failed"); + ad->error_type = CAM_ERROR_TYPE_UNABLE_TO_LAUNCH; + } + } + + if(ad->error_type == CAM_ERROR_TYPE_UNABLE_TO_LAUNCH){ + cam_utils_request_main_pipe_handler(ad, NULL, CAM_MAIN_PIPE_OP_TYPE_ERROR_POPUP); + } + + ad->camera_start_thread = NULL; + pthread_exit(NULL); + + return NULL; +} + +static void __accelerometer_cb(unsigned long long timestamp, sensor_data_accuracy_e accuracy, float x, float y, float z, void *user_data) +{ + #define RADIAN_VALUE (57.2957) + #define PITCH_MIN 35 + #define PITCH_MAX 145 + + struct appdata *ad = (struct appdata *)user_data; + cam_retm_if(ad == NULL, "appdata is NULL"); + + if (ad->ug_state == CAM_UG_TERMINATE_STATE + || ad->ug_state == CAM_UG_PAUSE_STATE) {/*NOTE: in pause state, and terminate state, not cb*/ + return ; + } + + double atan_v, norm_z, raw_z; + int acc_theta, acc_pitch; + + static app_device_orientation_e rotate = APP_DEVICE_ORIENTATION_0; + + atan_v = atan2(y, x); + acc_theta = (int)(atan_v * (RADIAN_VALUE) + 270)%360; + raw_z = (double)(z/(0.004 * 9.81)); + + if (raw_z > 250) { + norm_z = 1.0; + } else if (raw_z < -250) { + norm_z = -1.0; + } else { + norm_z = ((double)raw_z)/250; + } + + acc_pitch = (int)(acos(norm_z) * (RADIAN_VALUE)); + + if ((acc_pitch > 35) && (acc_pitch < 145)) { + if ((acc_theta >= 315 && acc_theta <= 359) || (acc_theta >=0 && acc_theta < 45)) { + rotate = APP_DEVICE_ORIENTATION_0; + } else if (acc_theta >= 45 && acc_theta < 135) { + rotate = APP_DEVICE_ORIENTATION_90; + } else if (acc_theta >= 135 && acc_theta < 225) { + rotate = APP_DEVICE_ORIENTATION_180; + } else if (acc_theta >= 225 && acc_theta < 315) { + rotate = APP_DEVICE_ORIENTATION_270; + } + } + + ad->rot_current = rotate; + if (ad->rot_previous != rotate) { + if(__device_orientation_cb(rotate, (void*)ad)){ + ad->rot_previous = ad->rot_current; + } + } +} + +static gboolean __start_sensor(void* data) +{ + struct appdata *ad = (struct appdata *)data; + cam_retvm_if(ad == NULL, FALSE, "appdata is NULL"); + + int ret = -1; + ret = sensor_create(&ad->sensor); + if(ret != SENSOR_ERROR_NONE) + { + cam_critical(LOG_UI, "sensor_create fail %d", ret); + return FALSE; + } + + + bool is_supported = FALSE; + + + ret = sensor_is_supported(SENSOR_ACCELEROMETER, &is_supported); + if(ret != SENSOR_ERROR_NONE) + { + cam_critical(LOG_UI, "sensor_create fail %d", ret); + return FALSE; + } + + if (is_supported == FALSE) { + cam_critical(LOG_UI, "sensor_create fail %d", ret); + }else{ + + sensor_accelerometer_set_cb(ad->sensor, 300, __accelerometer_cb, (void*)ad); + ret = sensor_start(ad->sensor, SENSOR_ACCELEROMETER ); + + if(ret != SENSOR_ERROR_NONE) + { + cam_critical(LOG_UI, "sensor_start fail %d", ret); + return FALSE; + } + } + + return TRUE; +} + +UG_MODULE_API int UG_MODULE_INIT(struct ug_module_ops *ops) +{ + struct appdata *ugd; + + cam_debug(LOG_UI, "UG_MODULE_INIT"); + + if (!ops) { + cam_critical(LOG_UI, "ops is NULL"); + return -1; + } + + ugd = calloc(1, sizeof(struct appdata)); + if (!ugd) { + cam_critical(LOG_UI, "Memory allocation failed."); + return -1; + } + + CAM_TA_INIT(); + g_type_init(); + + ops->create = on_create; + ops->start = on_start; + ops->pause = on_pause; + ops->resume = on_resume; + ops->destroy = on_destroy; + ops->message = on_message; + ops->event = on_event; + ops->priv = ugd; + ops->opt = UG_OPT_INDICATOR_DISABLE; + + return 0; +} + +UG_MODULE_API void UG_MODULE_EXIT(struct ug_module_ops *ops) +{ + struct appdata *ugd; + + cam_debug(LOG_UI, "UG_MODULE_EXIT"); + + if (!ops) { + cam_critical(LOG_UI, "ops is NULL"); + return; + } + + ugd = ops->priv; + if (ugd) + free(ugd); + + CAM_TA_RELEASE(); +} + +//end file |