Flora license update
[apps/core/preloaded/ug-camera-efl.git] / src / cam.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *        http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18
19 #ifndef UG_MODULE_API
20 #define UG_MODULE_API __attribute__ ((visibility("default")))
21 #endif
22
23
24 #include <stdio.h>
25 #include <pthread.h>
26 #include <X11/Xlib.h>
27 #include <utilX.h>
28 #include <power.h>
29 #include <ui-gadget-module.h>
30 #include "cam.h"
31 #include "cam_app.h"
32 #include "camera_utils.h"
33 #include "cam_ta.h"
34 #include "cam_mm.h"
35 #include "cam_debug.h"
36 #include "cam_toolbar_edc_callback.h"
37 #include "cam_zoom_edc_callback.h"
38 #include "cam_indicator_edc_callback.h"
39 #include "cam_common_edc_callback.h"
40 #include "cam_rec.h"
41 #include "cam_file.h"
42 #include "cam_menu_composer.h"
43 #include "cam_device_capacity.h"
44
45
46 #define CAM_EXT_LIB_PATH "/usr/lib/libcamera-external-engine.so"
47
48 void *handle = NULL;
49
50
51 static Evas_Object *__create_base_layout(Evas_Object *parent);
52 static void __low_battery_cb(void *data);
53 static gboolean __device_orientation_cb(app_device_orientation_e mode, void *data);
54 static int __is_idle_lock(void);
55 static Eina_Bool __resume_camera(void* data);
56 static int __convert_orientation_to_angle(app_device_orientation_e orientation);
57 void *__cam_start_thread_run(void *data);
58 static void __accelerometer_cb(unsigned long long timestamp, sensor_data_accuracy_e accuracy, float x, float y, float z, void *user_data);
59 static gboolean __start_sensor(void* data);
60
61
62 static void *on_create(ui_gadget_h ug, enum ug_mode mode, service_h service, void *priv)
63 {
64         CAM_TA_ACUM_ITEM_BEGIN("==on_create==", 0);
65         cam_debug(LOG_UI, "############## on_create START ##############");
66
67         cam_retvm_if(ug == NULL, NULL, "ui_gadget_h is NULL");
68         struct appdata *ad = (struct appdata *)priv;
69         cam_retvm_if(ad == NULL, NULL, "appdata is NULL");
70         Ecore_X_Display *dpy = NULL;
71
72         bindtextdomain(PACKAGE, "/usr/ug/res/locale");
73
74         ad->camera_ug = ug;
75
76         /* get parent's layout */
77         ad->win_main = ug_get_window();
78         cam_retvm_if(ad->win_main == NULL, NULL, "ug_get_window failed");
79
80         /* create base layout */
81         ad->ug_base = __create_base_layout(ad->win_main);
82         cam_retvm_if(ad->ug_base == NULL, NULL, "__create_base_layout failed");
83
84         /* Camera does not support desktop mode */
85         const char *str = "mobile";
86         elm_win_profiles_set(ad->win_main, &str, 1);
87
88         /* remove effect */
89         dpy = ecore_x_display_get();
90         if (dpy) {
91                 Ecore_X_Window win;
92                 win = elm_win_xwindow_get(ad->win_main);
93
94                 cam_debug(LOG_UI, "dpy is not null .. set no effect to display = %d\n", win);
95                 utilx_set_window_effect_style(dpy, win,
96                                               UTILX_EFFECT_TYPE_ROTATION,
97                                               UTILX_EFFECT_STYLE_NONE);
98         }
99
100         ad->evas = evas_object_evas_get(ad->win_main);
101         ad->ee = ecore_evas_ecore_evas_get(ad->evas);
102         ad->main_xid = elm_win_xwindow_get(ad->win_main);
103
104         /* camera application initialization */
105         CAM_TA_ACUM_ITEM_BEGIN("  cam_app_init", 0);
106         if (!cam_app_init(ad)) {
107                 cam_critical(LOG_UI, "cam_app_init failed");
108                 return NULL;
109         }
110         CAM_TA_ACUM_ITEM_END("  cam_app_init", 0);
111
112         /*add camera exteral engine lib load*/
113         if (!open_cam_ext_handle()) {
114                 cam_critical(LOG_UI, "open_cam_ext_handle failed");
115         }
116
117         ad->rot_current = app_get_device_orientation();
118         ad->rot_previous = ad->rot_current;
119         int win_angle = elm_win_rotation_get(ad->win_main);
120         ad->angle = __convert_orientation_to_angle(ad->rot_current);
121
122         if(win_angle != ad->angle) {
123                 cam_critical(LOG_UI, "win_angle:%d device_angle:%d ", win_angle, ad->angle);
124                 elm_win_rotation_with_resize_set(ad->win_main, ad->angle);
125         }
126
127         evas_object_show(ad->win_main);
128
129         if (!cam_check_dir()) {
130                 cam_app_notice_popup(ad, "Cannot make default path", cam_app_timeout_notice_response_cb);
131                 return NULL;
132         }
133
134         if (!cam_utils_check_torchlight_status(ad)) {
135                 DEBUG_TRACE("Can not get torchlight status");
136         }
137
138         /* remove exe args */
139         if (ad->exe_args) {
140                 if (ad->exe_args->caller) {
141                         free(ad->exe_args->caller);
142                         ad->exe_args->caller = NULL;
143                 }
144                 free(ad->exe_args);
145                 ad->exe_args = NULL;
146         }
147
148         char *operation = NULL;
149         int ret = service_get_operation(service, &operation);
150         if (ret != SERVICE_ERROR_NONE) {
151                 cam_critical(LOG_UI, "service_get_operation failed");
152                 return NULL;
153         }
154
155         if (operation == NULL) {
156                 cam_critical(LOG_UI, "operation is null");
157                 return NULL;
158         }
159
160         if (strcmp(operation, SERVICE_OPERATION_CREATE_CONTENT) == 0) {
161                 cam_debug(LOG_UI, "Operation is SERVICE_OPERATION_CREATE_CONTENT");
162
163                 ad->launching_mode = CAM_LAUNCHING_MODE_EXTERNAL;
164
165                 ret = service_clone(&ad->service_handle, service);
166                 if (ret != SERVICE_ERROR_NONE) {
167                         cam_critical(LOG_UI, "service_clone failed");
168                         return NULL;
169                 }
170
171                 CamExeArgs *args = (CamExeArgs *)malloc(sizeof(CamExeArgs));
172                 if (args == NULL) {
173                         cam_critical(LOG_UI, "Memory allocation failed");
174                         return NULL;
175                 }
176                 memset(args, 0, sizeof(CamExeArgs));
177
178                 if (!cam_app_parse_args(args, service)) {
179                         cam_critical(LOG_UI, "cam_app_parse_args failed");
180                         if (args) {
181                                 if (args->caller) {
182                                         free(args->caller);
183                                         args->caller = NULL;
184                                 }
185                                 free(args);
186                                 args = NULL;
187                         }
188                         return NULL;
189                 }
190                 ad->exe_args = args;
191
192                 if (!cam_mm_create(CAM_DEVICE_MEGA, ad->exe_args->cam_mode)) {
193                         cam_critical(LOG_MM, "cam_mm_create failed");
194                         ad->error_type = CAM_ERROR_TYPE_UNABLE_TO_LAUNCH;
195                         return NULL;
196                 }
197
198                 CAM_TA_ACUM_ITEM_BEGIN("    cam_handle_init", 0);
199                 if (!cam_handle_init(ad, ad->exe_args->cam_mode)) {
200                         cam_critical(LOG_CAM, "cam_handle_init failed");
201                         return NULL;
202                 }
203                 CAM_TA_ACUM_ITEM_END("    cam_handle_init", 0);
204
205                 cam_app_init_with_args(ad);
206         } else {
207                 ad->launching_mode = CAM_LAUNCHING_MODE_NORMAL;
208
209                 if (!cam_mm_create(CAM_DEVICE_MEGA, CAM_CAMERA_MODE)) {
210                         cam_critical(LOG_MM, "cam_mm_create failed");
211                         ad->error_type = CAM_ERROR_TYPE_UNABLE_TO_LAUNCH;
212                         return NULL;
213                 }
214
215                 CAM_TA_ACUM_ITEM_BEGIN("    cam_handle_init", 0);
216                 if (!cam_handle_init(ad, CAM_CAMERA_MODE)) {
217                         cam_critical(LOG_CAM, "cam_handle_init failed");
218                         return NULL;
219                 }
220                 CAM_TA_ACUM_ITEM_END("    cam_handle_init", 0);
221         }
222
223         ad->error_type = CAM_ERROR_TYPE_NONE;
224
225         if (cam_utils_check_battery_critical_low()) {
226                 ad->battery_status = LOW_BATTERY_CRITICAL_STATUS;
227         } else if (cam_utils_check_battery_warning_low()) {
228                 ad->battery_status = LOW_BATTERY_WARNING_STATUS;
229         } else {
230                 ad->battery_status = NORMAL_BATTERY_STATUS;
231         }
232
233         if (cam_utils_check_call_running())
234                 ad->is_calling = TRUE;
235         else
236                 ad->is_calling = FALSE;
237
238         if ( ad->battery_status != LOW_BATTERY_CRITICAL_STATUS
239                 || ad->is_calling == FALSE) {
240                 if (pthread_create(&(ad->camera_start_thread), NULL, __cam_start_thread_run, (void *)ad) < 0) {
241                         cam_critical(LOG_CAM, "Create camera start thread failed");
242                         return NULL;
243                 }
244         }
245
246         cam_debug(LOG_UI, "############## on_create END ##############");
247         CAM_TA_ACUM_ITEM_END("==on_create==", 0);
248
249         return ad->ug_base;
250 }
251
252 static void on_start(ui_gadget_h ug, service_h service, void *priv)
253 {
254         CAM_TA_ACUM_ITEM_BEGIN("==on_start==", 0);
255         cam_debug(LOG_UI, "############## on_start START ##############");
256
257         cam_retm_if(ug == NULL, "ui_gadget_h is NULL");
258         struct appdata *ad = (struct appdata *)priv;
259         cam_retm_if(ad == NULL, "appdata is NULL");
260         CamAppData *camapp = ad->camapp_handle;
261         cam_retm_if(camapp == NULL, "camapp_handle is NULL");
262
263         ad->ug_state = CAM_UG_RESET_STATE;
264
265 #ifdef EFL_TEMP_CODE
266         cam_win_transparent_set(ad);
267 #endif
268
269         cam_app_get_win_size(ad);
270
271         power_lock_state(POWER_STATE_NORMAL, 0);
272
273         /*elm_win_alpha_set(ad->win_main, EINA_TRUE);*/
274
275         ad->setting_menu_composer = NULL;
276
277         if( ad->setting_menu_composer == NULL){
278                 ad->setting_menu_composer = calloc(1, sizeof(cam_menu_composer));
279                 cam_compose_setting_menu((void*)ad, ad->setting_menu_composer);
280         }
281
282         CAM_TA_ACUM_ITEM_BEGIN("    cam_layout_init", 0);
283         if (!cam_layout_init(ad)) {
284                 cam_critical(LOG_UI, "cam_layout_init failed");
285                 return;
286         }
287         CAM_TA_ACUM_ITEM_END("    cam_layout_init", 0);
288
289         __start_sensor(ad);
290
291         cam_debug(LOG_UI, "############## on_start END##############");
292         CAM_TA_ACUM_ITEM_END("==cam_service==", 0);
293 }
294
295 static void on_pause(ui_gadget_h ug, service_h service, void *priv)
296 {
297         CAM_TA_ACUM_ITEM_BEGIN("==on_pause==", 0);
298         cam_debug(LOG_UI, "############## on_pause ##############");
299
300         cam_retm_if(ug == NULL, "ui_gadget_h is NULL");
301         struct appdata *ad = (struct appdata *)priv;
302         cam_retm_if(ad == NULL, "appdata is NULL");
303         CamAppData *camapp = ad->camapp_handle;
304         cam_retm_if(camapp == NULL, "camapp_handle is NULL");
305
306         ad->ug_state = CAM_UG_PAUSE_STATE;
307
308         int ret = -1;
309         ret = sensor_stop(ad->sensor, SENSOR_ACCELEROMETER);
310         if(ret != SENSOR_ERROR_NONE){
311                 cam_critical(LOG_MM, "sensor_stop fail %d", ret);
312                 return;
313         }
314
315         if (ad->location_ug) {
316                 ug_destroy(ad->location_ug);
317                 ad->location_ug = NULL;
318         }
319
320         if (ad->imageviewer_ug) {
321                 DEBUG_TRACE("imageviewer_ug exist");
322                 return;
323         }
324
325         CAM_TA_ACUM_ITEM_BEGIN("  app_stop", 0);
326         DEBUG_TRACE(" ");
327
328         cam_app_pause(ad);
329
330         power_unlock_state(POWER_STATE_NORMAL);
331         CAM_TA_ACUM_ITEM_END("  app_stop", 0);
332
333         CAM_TA_ACUM_ITEM_END("==on_pause==", 0);
334 }
335
336 static void on_resume(ui_gadget_h ug, service_h service, void *priv)
337 {
338         CAM_TA_ACUM_ITEM_BEGIN("==on_resume==", 0);
339         cam_debug(LOG_UI, "############## on_resume ##############");
340
341         cam_retm_if(ug == NULL, "ui_gadget_h is NULL");
342         struct appdata *ad = (struct appdata *)priv;
343         cam_retm_if(ad == NULL, "appdata is NULL");
344         CamAppData *camapp = ad->camapp_handle;
345         cam_retm_if(camapp == NULL, "camapp_handle is NULL");
346
347         ad->ug_state = CAM_UG_RESUME_STATE;
348
349         evas_object_raise(ad->win_main);
350
351         if (!cam_check_dir()) {
352                 cam_app_notice_popup(ad, "Cannot make default path",
353                          cam_app_timeout_notice_response_cb);
354                 return;
355         }
356
357         int ret = -1;
358         ret =  sensor_start(ad->sensor, SENSOR_ACCELEROMETER);
359         if(ret != SENSOR_ERROR_NONE){
360                 cam_critical(LOG_MM, "sensor_start fail %d ", ret);
361                 return;
362         }
363
364         cam_mm_set_display_visible(TRUE);
365
366         if (!cam_utils_check_torchlight_status(ad)) {
367                 DEBUG_TRACE("Can not get torchlight status");
368         }
369
370         app_device_orientation_e rot_current = app_get_device_orientation();
371         DEBUG_TRACE("rot_current:%d, ad->rot_current:%d, ad->angle:%d", rot_current, ad->rot_current, ad->angle);
372         if (rot_current != ad->rot_current) {
373                 ecore_idler_add(__resume_camera, ad);
374         }
375
376         if (ad->imageviewer_ug) {       /* bug fix camera app overlab with imageviewer_ug */
377                 DEBUG_TRACE("imageviewer_ug exist");
378                 return;
379         }
380
381         power_lock_state(POWER_STATE_NORMAL, 0);
382
383         CAM_TA_INIT();
384
385         if (ad) {
386                 CAM_TA_ACUM_ITEM_BEGIN("  cam_app_resume", 0);
387                 if (!cam_app_resume(ad))
388                         return;
389                 CAM_TA_ACUM_ITEM_END("  cam_app_resume", 0);
390         }
391
392         CAM_TA_ACUM_ITEM_END("==on_resume==", 0);
393 }
394
395 static void on_destroy(ui_gadget_h ug, service_h service, void *priv)
396 {
397         CAM_TA_ACUM_ITEM_BEGIN("==on_destroy==", 0);
398         cam_debug(LOG_UI, "############## on_destroy ##############");
399
400         cam_retm_if(ug == NULL, "ui_gadget_h is NULL");
401         struct appdata *ad = (struct appdata *)priv;
402         cam_retm_if(ad == NULL, "appdata is NULL");
403
404         ad->ug_state = CAM_UG_TERMINATE_STATE;
405
406     sensor_accelerometer_unset_cb(ad->sensor);
407         if(sensor_stop(ad->sensor, SENSOR_ACCELEROMETER) == SENSOR_ERROR_NONE)
408                 sensor_destroy(ad->sensor);
409
410         if (ad->camera_start_thread) {
411                 pthread_join(ad->camera_start_thread, NULL);
412         }
413
414 #ifdef USE_FIFO_THREAD
415         cam_app_FIFO_thread_exit();
416 #endif
417
418         cam_app_file_register_thread_exit(ad);
419
420         cam_continuous_shot_file_save_thread_exit(ad);
421         CAM_TA_ACUM_ITEM_BEGIN("  cam_app_stop", 0);
422         cam_app_stop(ad);
423         CAM_TA_ACUM_ITEM_END("  cam_app_stop", 0);
424
425         power_unlock_state(POWER_STATE_NORMAL);
426
427         CAM_TA_ACUM_ITEM_SHOW_RESULT_TO(CAM_TA_SHOW_FILE);
428         CAM_TA_RELEASE();
429
430         close_cam_ext_handle();
431
432         CAM_TA_ACUM_ITEM_END("==on_destroy==", 0);
433 }
434
435 static void on_message(ui_gadget_h ug, service_h msg, service_h service, void *priv)
436 {
437         cam_critical(LOG_UI, "############## on_message ##############");
438
439         cam_retm_if(ug == NULL, "ui_gadget_h is NULL");
440         struct appdata *ad = (struct appdata *)priv;
441         cam_retm_if(ad == NULL, "appdata is NULL");
442
443         /* Check service for DFT mmi-check */
444         if ((ad->ug_state == CAM_UG_RESUME_STATE) || (ad->ug_state == CAM_UG_RESET_STATE)) {
445                 char *mmi_check = NULL;
446                 service_get_extra_data(service, "MMICHECK_CAMERA", (char **)&mmi_check);
447                 if (mmi_check) {
448                         cam_critical(LOG_UI, "MMICHECK_CAMERA %s", mmi_check);
449                         if (0 == strcmp(mmi_check, "1")) {
450                                 if (!cam_do_capture(ad)) {
451                                         cam_critical(LOG_UI, "cam_do_capture failed");
452                                 }
453                         }
454                 } else {
455                         cam_critical(LOG_UI, "not mmi check case, error!");
456                 }
457         }
458 }
459
460 static void on_event(ui_gadget_h ug, enum ug_event event, service_h service, void *priv)
461 {
462         cam_critical(LOG_UI, "############## on_event ##############");
463
464         cam_retm_if(ug == NULL, "ui_gadget_h is NULL");
465         struct appdata *ad = (struct appdata *)priv;
466         cam_retm_if(ad == NULL, "appdata is NULL");
467
468         switch (event) {
469         case UG_EVENT_LOW_BATTERY:
470                 __low_battery_cb(ad);
471                 break;
472         case UG_EVENT_LANG_CHANGE:
473         case UG_EVENT_ROTATE_PORTRAIT:
474         case UG_EVENT_ROTATE_LANDSCAPE:
475         case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
476         case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
477         case UG_EVENT_LOW_MEMORY:
478         case UG_EVENT_REGION_CHANGE:
479         default:
480                 DEBUG_TRACE("Ignore Event - [%d]", event);
481                 break;
482         }
483 }
484
485 gboolean open_cam_ext_handle()
486 {
487         if (!handle) {
488                 /*NOTE: RTLD_LAZY: it will check dynamic lib api while use it,
489                                 RTLD_NOW: it will check each api before open dynamic lib*/
490                 handle = dlopen(CAM_EXT_LIB_PATH, RTLD_LAZY);
491                 if ( !handle ) {
492                         char *msg = NULL;
493                         msg = strdup(dlerror());
494                         DEBUG_TRACE("error: %s", msg);
495                         return FALSE;
496                 }
497         }
498         return TRUE;
499 }
500
501 void close_cam_ext_handle()
502 {
503         if (handle) {
504                 dlclose(handle);
505                 handle = NULL;
506         }
507 }
508
509 static Evas_Object *__create_base_layout(Evas_Object *parent)
510 {
511         Evas_Object *base;
512         int r = 0;
513
514         base = elm_layout_add(parent);
515         cam_retvm_if(base == NULL, NULL, "elm_layout_add failed");
516
517         r = elm_layout_file_set(base, CAM_MAIN_LAYOUT_EDJ_NAME, "main_layout");
518         if (!r) {
519                 evas_object_del(base);
520                 return NULL;
521         }
522
523         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
524         evas_object_show(base);
525
526         return base;
527 }
528
529 static void __low_battery_cb(void *data)
530 {
531         cam_info(LOG_SYS, "Low battery !!");
532
533         struct appdata *ad = (struct appdata *)data;
534         cam_retm_if(ad == NULL, "appdata is NULL");
535         CamAppData *camapp = ad->camapp_handle;
536         cam_retm_if(camapp == NULL, "camapp_handle is NULL");
537
538         if (evas_object_visible_get(ad->win_main)) {
539                 int state = cam_mm_get_state();
540                 if ((state == RECORDER_STATE_RECORDING
541                     || state == RECORDER_STATE_PAUSED)
542                     &&camapp->camera_mode == CAM_CAMCORDER_MODE) {
543                         camapp->rec_stop_type = CAM_REC_STOP_LOW_BATTERY;
544                         ad->recording_commit =
545                             ecore_idler_add(cam_video_idler_record_stop, ad);
546                 } else {
547                         cam_app_exit(ad);
548                 }
549         }
550 }
551
552 static gboolean __device_orientation_cb(app_device_orientation_e mode, void *data)
553 {
554         cam_debug(LOG_UI, "############## cam_device_orientation_cb ##############");
555
556         struct appdata *ad = (struct appdata *)data;
557         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
558         cam_retvm_if(ad->camapp_handle == NULL, FALSE, "ad->camapp_handle is NULL");
559
560         if(ad->camapp_handle->continuous_shot_data &&
561                         ad->camapp_handle->continuous_shot_data->capture_status == CAM_CONTI_SHOT_STATUS_CAPTURING){
562                 cam_debug(LOG_UI, "capturing");
563                 return FALSE;
564         }
565         if (ad->bestshot_thumbnails_edje) {
566                 cam_debug(LOG_UI, "is creating best shot thumbnails");
567                 return FALSE;
568         }
569         cam_debug(LOG_UI, "rotated : %d", mode);
570
571         /*TODO: now just return, if the last rotated is not finished*/
572         if (ad->is_rotating) {
573                 cam_debug(LOG_UI, "rotating...");
574                 return FALSE;
575         }
576
577         int angle = 0;
578         ui_gadget_h ug = NULL;
579
580         enum ug_event ev = UG_EVENT_ROTATE_LANDSCAPE;
581         ad->rot_previous = ad->rot_current;
582         ad->rot_current = mode;
583
584         if (ad->toolbar_edj_file)
585                 free(ad->toolbar_edj_file);
586         ad->toolbar_edj_file = NULL;
587
588         switch (mode) {
589         case APP_DEVICE_ORIENTATION_0:
590                 angle = 0;
591                 ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT;
592                 ev = UG_EVENT_ROTATE_PORTRAIT;
593                 ad->camcorder_rotate = CAMERA_ROTATION_90;
594                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_EDJ_NAME);
595                 break;
596         case APP_DEVICE_ORIENTATION_270:
597                 angle = 270;
598                 ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE;
599                 ev = UG_EVENT_ROTATE_LANDSCAPE;
600                 ad->camcorder_rotate = CAMERA_ROTATION_NONE;
601                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_EDJ_NAME);
602                 break;
603         case APP_DEVICE_ORIENTATION_180:
604                 angle = 180;
605                 ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT_INVERSE;
606                 ev = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN;
607                 ad->camcorder_rotate = CAMERA_ROTATION_270;
608                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_INVERSE_EDJ_NAME);
609                 break;
610         case APP_DEVICE_ORIENTATION_90:
611                 angle = 90;
612                 ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE_INVERSE;
613                 ev = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN;
614                 ad->camcorder_rotate = CAMERA_ROTATION_180;
615                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_INVERSE_EDJ_NAME);
616                 break;
617
618         default:
619                 break;
620         }
621         ad->angle = angle;
622
623         if (ad->imageviewer_ug) {
624                 ug = ad->imageviewer_ug;
625         } else if (ad->location_ug) {
626                 ug = ad->location_ug;
627         }
628         if (ug) {
629                 enum ug_mode md = ug_get_mode(ug);
630                 if (md == UG_MODE_FULLVIEW) {
631
632                         int rotate = 0;
633                         int ret = -1;
634
635                         ret = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &rotate);
636                         if (ret != 0) {
637                                 return FALSE;
638                         }
639
640                         if (rotate == 0) {
641                                 cam_critical(LOG_UI, "Rotation is lock");
642                                 return FALSE;
643                         }
644
645                         elm_win_rotation_with_resize_set(ad->win_main, angle);
646                         /* send event to ug */
647                         ug_send_event(ev);
648                 }
649         } else {
650
651                 cam_utils_request_main_pipe_handler(ad, NULL, CAM_MAIN_PIPE_OP_TYPE_ROTATE_ANIMATOR);
652         }
653
654         return TRUE;
655 }
656
657 static int __is_idle_lock(void)
658 {
659         int vconf_val = 0;
660         int vconf_ret = 0;
661
662         vconf_ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &vconf_val);
663         if(vconf_ret == 0){
664                 if (vconf_val == VCONFKEY_IDLE_LOCK) {
665                         DEBUG_TRACE("  IDLE IN LOCK STATE  ");
666                         return 1;
667                 }
668         }
669
670         return 0;
671 }
672
673 static Eina_Bool __resume_camera(void *data)
674 {
675         struct appdata *ad = data;
676         cam_retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "appdata is NULL");
677
678         ad->rot_current = app_get_device_orientation();
679         ad->rot_previous = ad->rot_current;
680         int angle = 0;
681         ui_gadget_h ug = NULL;
682         enum ug_event ev = UG_EVENT_ROTATE_LANDSCAPE;
683         switch (ad->rot_current) {
684         case APP_DEVICE_ORIENTATION_0:
685                 angle = 0;
686                 ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT;
687                 ev = UG_EVENT_ROTATE_PORTRAIT;
688                 ad->camcorder_rotate = CAMERA_ROTATION_90;
689                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_EDJ_NAME);
690                 break;
691         case APP_DEVICE_ORIENTATION_270:
692                 angle = 270;
693                 ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE;
694                 ev = UG_EVENT_ROTATE_LANDSCAPE;
695                 ad->camcorder_rotate = CAMERA_ROTATION_NONE;
696                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_EDJ_NAME);
697                 break;
698         case APP_DEVICE_ORIENTATION_180:
699                 angle = 180;
700                 ad->target_direction = CAM_TARGET_DIRECTION_PORTRAIT_INVERSE;
701                 ev = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN;
702                 ad->camcorder_rotate = CAMERA_ROTATION_270;
703                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_VERTICAL_INVERSE_EDJ_NAME);
704                 break;
705         case APP_DEVICE_ORIENTATION_90:
706                 angle = 90;
707                 ad->target_direction = CAM_TARGET_DIRECTION_LANDSCAPE_INVERSE;
708                 ev = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN;
709                 ad->camcorder_rotate = CAMERA_ROTATION_180;
710                 ad->toolbar_edj_file = strdup(CAM_TOOLBAR_LAYOUT_INVERSE_EDJ_NAME);
711                 break;
712
713         default:
714                 break;
715         }
716         ad->angle = angle;
717         if (ad->imageviewer_ug) {
718                 ug = ad->imageviewer_ug;
719         } else if (ad->location_ug) {
720                 ug = ad->location_ug;
721         }
722         if (ug) {
723                 enum ug_mode md = ug_get_mode(ug);
724                 if (md == UG_MODE_FULLVIEW) {
725                         elm_win_rotation_with_resize_set(ad->win_main, ad->angle);
726                         /* send event to ug      */
727                         ug_send_event(ev);
728                 }
729         } else {
730                 cam_utils_request_main_pipe_handler(ad, NULL, CAM_MAIN_PIPE_OP_TYPE_ROTATE_ANIMATOR);
731         }
732         return ECORE_CALLBACK_CANCEL;
733
734 }
735
736 static int __convert_orientation_to_angle(app_device_orientation_e orientation)
737 {
738
739         switch (orientation) {
740         case APP_DEVICE_ORIENTATION_0:
741                 return 0;
742                 break;
743         case APP_DEVICE_ORIENTATION_180:
744                 return 180;
745                 break;
746         case APP_DEVICE_ORIENTATION_270:
747                 return 270;
748                 break;
749         case APP_DEVICE_ORIENTATION_90:
750                 return 90;
751                 break;
752         default:
753                 return 0;
754         }
755 }
756
757 void *__cam_start_thread_run(void *data)
758 {
759         struct appdata *ad = (struct appdata *)data;
760         cam_retv_if(ad == NULL, NULL);
761
762         if(cam_mm_is_created()){
763                 if (!cam_app_start(ad)){
764                         cam_critical(LOG_CAM, "cam_app_start failed");
765                         ad->error_type = CAM_ERROR_TYPE_UNABLE_TO_LAUNCH;
766                 }
767         }
768
769         if(ad->error_type == CAM_ERROR_TYPE_UNABLE_TO_LAUNCH){
770                 cam_utils_request_main_pipe_handler(ad, NULL, CAM_MAIN_PIPE_OP_TYPE_ERROR_POPUP);
771         }
772
773         ad->camera_start_thread = NULL;
774         pthread_exit(NULL);
775
776         return NULL;
777 }
778
779 static void __accelerometer_cb(unsigned long long timestamp, sensor_data_accuracy_e accuracy, float x, float y, float z, void *user_data)
780 {
781         #define RADIAN_VALUE (57.2957)
782         #define PITCH_MIN       35
783         #define PITCH_MAX       145
784
785         struct appdata *ad = (struct appdata *)user_data;
786         cam_retm_if(ad == NULL, "appdata is NULL");
787
788         if (ad->ug_state == CAM_UG_TERMINATE_STATE
789                 || ad->ug_state == CAM_UG_PAUSE_STATE) {/*NOTE: in pause state, and terminate state, not cb*/
790                 return ;
791         }
792
793         double atan_v, norm_z, raw_z;
794         int acc_theta, acc_pitch;
795
796         static app_device_orientation_e rotate = APP_DEVICE_ORIENTATION_0;
797
798         atan_v = atan2(y, x);
799         acc_theta = (int)(atan_v * (RADIAN_VALUE) + 270)%360;
800         raw_z = (double)(z/(0.004 * 9.81));
801
802         if (raw_z > 250) {
803                 norm_z = 1.0;
804         } else if (raw_z < -250) {
805                 norm_z = -1.0;
806         } else {
807                 norm_z = ((double)raw_z)/250;
808         }
809
810         acc_pitch = (int)(acos(norm_z) * (RADIAN_VALUE));
811
812         if ((acc_pitch > 35) && (acc_pitch < 145)) {
813                 if ((acc_theta >= 315 && acc_theta <= 359) || (acc_theta >=0 && acc_theta < 45)) {
814                         rotate = APP_DEVICE_ORIENTATION_0;
815                 } else if (acc_theta >= 45 && acc_theta < 135) {
816                         rotate = APP_DEVICE_ORIENTATION_90;
817                 } else if (acc_theta >= 135 && acc_theta < 225) {
818                         rotate = APP_DEVICE_ORIENTATION_180;
819                 } else if (acc_theta >= 225 && acc_theta < 315) {
820                         rotate = APP_DEVICE_ORIENTATION_270;
821                 }
822         }
823
824         ad->rot_current = rotate;
825         if (ad->rot_previous != rotate) {
826                 if(__device_orientation_cb(rotate, (void*)ad)){
827                         ad->rot_previous = ad->rot_current;
828                 }
829         }
830 }
831
832 static gboolean __start_sensor(void* data)
833 {
834         struct appdata *ad = (struct appdata *)data;
835         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
836
837         int ret = -1;
838         ret = sensor_create(&ad->sensor);
839         if(ret != SENSOR_ERROR_NONE)
840         {
841                 cam_critical(LOG_UI, "sensor_create fail %d", ret);
842                 return FALSE;
843         }
844
845
846         bool is_supported = FALSE;
847
848
849         ret = sensor_is_supported(SENSOR_ACCELEROMETER, &is_supported);
850         if(ret != SENSOR_ERROR_NONE)
851         {
852                 cam_critical(LOG_UI, "sensor_create fail %d", ret);
853                 return FALSE;
854         }
855
856         if (is_supported == FALSE) {
857                 cam_critical(LOG_UI, "sensor_create fail %d", ret);
858         }else{
859
860                 sensor_accelerometer_set_cb(ad->sensor, 300, __accelerometer_cb, (void*)ad);
861                 ret = sensor_start(ad->sensor, SENSOR_ACCELEROMETER );
862
863                 if(ret != SENSOR_ERROR_NONE)
864                 {
865                         cam_critical(LOG_UI, "sensor_start fail %d", ret);
866                         return FALSE;
867                 }
868         }
869
870         return TRUE;
871 }
872
873 UG_MODULE_API int UG_MODULE_INIT(struct ug_module_ops *ops)
874 {
875         struct appdata *ugd;
876
877         cam_debug(LOG_UI, "UG_MODULE_INIT");
878
879         if (!ops) {
880                 cam_critical(LOG_UI, "ops is NULL");
881                 return -1;
882         }
883
884         ugd = calloc(1, sizeof(struct appdata));
885         if (!ugd) {
886                 cam_critical(LOG_UI, "Memory allocation failed.");
887                 return -1;
888         }
889
890         CAM_TA_INIT();
891         g_type_init();
892
893         ops->create = on_create;
894         ops->start = on_start;
895         ops->pause = on_pause;
896         ops->resume = on_resume;
897         ops->destroy = on_destroy;
898         ops->message = on_message;
899         ops->event = on_event;
900         ops->priv = ugd;
901         ops->opt = UG_OPT_INDICATOR_DISABLE;
902
903         return 0;
904 }
905
906 UG_MODULE_API void UG_MODULE_EXIT(struct ug_module_ops *ops)
907 {
908         struct appdata *ugd;
909
910         cam_debug(LOG_UI, "UG_MODULE_EXIT");
911
912         if (!ops) {
913                 cam_critical(LOG_UI, "ops is NULL");
914                 return;
915         }
916
917         ugd = ops->priv;
918         if (ugd)
919                 free(ugd);
920
921         CAM_TA_RELEASE();
922 }
923
924 //end file