55d21fb0d41f6c7bb912dadabc20fadb6902de84
[apps/core/preloaded/ug-camera-efl.git] / src / cam_rec.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (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 #include <X11/Xlib.h>
19 #include <X11/keysymdef.h>
20 #include <sys/wait.h>
21 #include <pthread.h>
22 #include <power.h>
23
24 #include "cam.h"
25 #include "cam_app.h"
26 #include "cam_sound.h"
27 #include "cam_file.h"
28 #include "cam_ta.h"
29 #include "cam_error.h"
30 #include "cam_mm.h"
31 #include "cam_rec.h"
32 #include "cam_indicator_edc_callback.h"
33 #include "cam_recording_edc_callback.h"
34 #include "camera_utils.h"
35 #include "cam_popup.h"
36 #include "cam_lbs.h"
37 #include "cam_common_edc_callback.h"
38 #include "cam_toolbar_edc_callback.h"
39
40 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
41 static gint __cam_rec_sound_index_get(gint setting_index, gboolean start)
42 {
43         gint index = -1;
44
45         if (start) {            /*  start sound */
46                 switch (setting_index) {
47                 case CAM_SETTINGS_SOUND_1:
48                         index = CAM_SOUND_EFFECT_REC_START3;
49                         break;
50                 case CAM_SETTINGS_SOUND_2:
51                         index = CAM_SOUND_EFFECT_REC_START2;
52                         break;
53                 case CAM_SETTINGS_SOUND_3:
54                         index = CAM_SOUND_EFFECT_REC_START3;
55                         break;
56                 default:
57                         break;
58
59                 }
60         } else {                /*  commit sound */
61                 switch (setting_index) {
62
63                 case CAM_SETTINGS_SOUND_1:
64                         index = CAM_SOUND_EFFECT_REC_COMMIT3;
65                         break;
66                 case CAM_SETTINGS_SOUND_2:
67                         index = CAM_SOUND_EFFECT_REC_COMMIT2;
68                         break;
69                 case CAM_SETTINGS_SOUND_3:
70                         index = CAM_SOUND_EFFECT_REC_COMMIT3;
71                         break;
72                 default:
73                         break;
74                 }
75         }
76         return index;
77 }
78 #endif
79 static gchar *__get_tmpfile_name()
80 {
81         char tmpfile_name[256] = { 0 };
82         gchar *file_path = NULL;
83         file_path = (gchar *)cam_app_get_target_path();
84
85         snprintf(tmpfile_name, sizeof(tmpfile_name), "%s%s", file_path,
86                  TMPFILE_PREFIX);
87         DEBUG_TRACE("#####################tmpfile_name=%s", tmpfile_name);
88
89         if (g_file_test(tmpfile_name, G_FILE_TEST_EXISTS)) {
90                 DEBUG_TRACE("Error : tmp file exist on the %s", file_path);
91                 cam_remove_tmp_file();
92         }
93
94         return g_strdup(tmpfile_name);
95 }
96
97 gboolean cam_video_record_start(void *data)
98 {
99         struct appdata *ad = (struct appdata *)data;
100         CamAppData *camapp = NULL;
101         gchar *filename = NULL;
102
103         gint64 remain = 0;
104
105         debug_fenter(LOG_UI);
106
107         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
108         camapp = ad->camapp_handle;
109         cam_retvm_if(camapp == NULL, FALSE, "camapp_handle is NULL");
110
111         if (ad->is_recording == TRUE) {
112                 DEBUG_TRACE("Camera app is recording");
113                 return TRUE;
114         } else {
115                 cam_critical(LOG_UI, "start reocrd");
116         }
117
118         if (ad->is_rotating == TRUE) {
119                 DEBUG_TRACE("now in rotating target, do not start recording");
120                 return TRUE;
121         }
122
123         DEBUG_TRACE("start recording !!");
124
125         if (ad->timer_activated) {
126                 CAM_UI_LOG("timer activated!");
127                 return true;
128         }
129         gchar* target_path = (gchar*)cam_app_get_target_path();
130         if (target_path != NULL) {
131                 remain = cam_get_free_space(target_path);
132         }
133
134         if (remain <= REC_MMS_MIN_SPACE) {
135                 cam_app_notice_popup(ad, dgettext(PACKAGE, "IDS_CAM_BODY_UNABLE_TO_SAVE_NOT_ENOUGH_MEMORY"),
136                                      cam_app_popup_response_cb);
137                 return TRUE;
138         }
139
140         if (camapp->gps) {
141                 int gps_level = CAM_LBS_STATE_DISABLE;
142                 gps_level = cam_lbs_get_state();
143                 if (gps_level >=CAM_LBS_STATE_SERVICE_ENABLE) {
144                         double longitude = -1.0;
145                         double latitude = -1.0;
146                         double altitude = -1.0;
147                         time_t time_stamp = -1.0;
148                         if (cam_lbs_get_current_position(&longitude, &latitude, &altitude, &time_stamp)) {
149                                 DEBUG_TRACE("GEO TAG [longitude = %d, latitude = %d, altitude = %d]", longitude, latitude, altitude);
150                                 if ( !cam_mm_set_gps_data(latitude, longitude, (double)altitude))
151                                         DEBUG_TRACE("cam_mm_set_gps_data failed");
152                         }
153                 }
154         }
155
156         filename = __get_tmpfile_name();
157
158         if (filename) {
159                 cam_debug(LOG_UI, "FILE NAME : %s", filename);
160                 if (!cam_mm_set_filename(filename)) {
161                         cam_critical(LOG_MM, "cannot set filename");
162                         return FALSE;
163                 }
164                 free(filename);
165                 filename = NULL;
166         } else {
167                 cam_critical(LOG_MM, "cannot get filename");
168                 return FALSE;
169         }
170
171         /* flash on */
172         if (camapp->flash == CAM_FLASH_ON) {
173                 if (!cam_mm_set_flash(CAM_FLASH_MOVIE_ON)) {
174                         cam_critical(LOG_MM, "cam_mm_set_flash failed");
175                 }
176         } else {
177                 if (!cam_mm_set_flash(CAM_FLASH_OFF)) {
178                         cam_critical(LOG_MM, "cam_mm_set_flash failed");
179                 }
180         }
181
182 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
183 /* play start effect sound */
184         cam_sound_play(__cam_rec_sound_index_get(camapp->shutter_sound, TRUE),
185                        ad);
186 #endif
187 /* set sound path for recording MIC */
188         cam_sound_set_mic();
189
190 /* set orient tag */
191         cam_set_orient_value(ad);
192
193 /* mm rec */
194         if (!cam_mm_rec_start(NULL)) {
195                 cam_critical(LOG_MM, "cam_mm_rec_start failed");
196                 cam_app_notice_popup(data,
197                                         dgettext(PACKAGE, "IDS_CAM_POP_ERROR_RECORDING_FAIL"),
198                                         cam_app_timeout_notice_response_cb);
199                 return FALSE;
200         }
201         /* set recording state */
202         ad->is_recording = TRUE;
203
204 /* change recording view */
205
206         if (load_recording_edje(ad)) {
207                 cam_critical(LOG_UI, "load_recording_edje failed");
208                 cam_video_record_cancel(ad);
209                 return FALSE;
210         }
211
212         if (ad->indicator_edje)
213                 cam_indicator_update(ad);
214         else
215                 cam_indicator_create(ad);
216
217         settings_guideline_refresh(ad);
218         return TRUE;
219 }
220
221 gboolean cam_video_record_resume(void *data)
222 {
223         struct appdata *ad = (struct appdata *)data;
224         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
225
226         if (!cam_mm_rec_start(NULL)) {
227                 cam_critical(LOG_MM, "cam_mm_rec_start failed");
228                 cam_app_notice_popup(data,
229                                         dgettext(PACKAGE, "IDS_CAM_POP_ERROR_RECORDING_FAIL"),
230                                         cam_app_timeout_notice_response_cb);
231                 return FALSE;
232         }
233
234         return TRUE;
235 }
236
237 gboolean cam_video_record_pause(void *data)
238 {
239         struct appdata *ad = (struct appdata *)data;
240         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
241
242         if (!cam_mm_rec_pause(NULL)) {
243                 cam_critical(LOG_MM, "cam_mm_rec_start failed");
244                 return FALSE;
245         }
246         return TRUE;
247 }
248 Eina_Bool cam_video_idler_record_stop(void *data)
249 {
250         struct appdata *ad = (struct appdata *)data;
251         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
252
253         cam_video_record_stop(ad);
254
255         return ECORE_CALLBACK_CANCEL;
256 }
257
258 gboolean cam_video_record_stop(void *data)
259 {
260         struct appdata *ad = (struct appdata *)data;
261         CamAppData *camapp = NULL;
262         gboolean to_stop = FALSE;
263
264         debug_fenter(LOG_UI);
265
266         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
267         camapp = ad->camapp_handle;
268         cam_retvm_if(camapp == NULL, FALSE, "camapp_handle is NULL");
269
270         if (ad->recording_commit) {
271                 ecore_idler_del(ad->recording_commit);
272                 ad->recording_commit = NULL;
273         }
274 /*  check to_stop val */
275
276         if (!cam_mm_stop_focusing()){
277                 cam_critical(LOG_MM, "cam_mm_stop_focusing error ");
278         }
279 /* mm stop rec */
280         if (!cam_mm_rec_stop(to_stop)) {
281                 cam_critical(LOG_MM, "cam_mm_rec_stop failed");
282                 if (!cam_mm_rec_cancel())
283                         cam_critical(LOG_MM, "cam_mm_rec_cancel failed");
284
285                 cam_app_notice_popup(data,
286                                         dgettext(PACKAGE, "IDS_CAM_POP_ERROR_RECORDING_FAIL"),
287                                         cam_app_timeout_notice_response_cb);
288         }
289
290 /* flash off */
291         if (!cam_mm_set_flash(camapp->flash)) {
292                 cam_critical(LOG_MM, "cam_mm_set_flash failed");
293         }
294
295 /* set sound path for effect sound */
296 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
297 /* play end effect sound */
298         cam_sound_play(__cam_rec_sound_index_get(camapp->shutter_sound, FALSE), ad);
299 #endif
300 /*      cam_sound_play(CAM_SOUND_EFFECT_REC_COMMIT); */
301
302         return TRUE;
303 }
304
305 gboolean cam_video_record_cancel(void *data)
306 {
307         struct appdata *ad = (struct appdata *)data;
308         CamAppData *camapp = NULL;
309
310         debug_fenter(LOG_UI);
311
312         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
313         camapp = ad->camapp_handle;
314         cam_retvm_if(camapp == NULL, FALSE, "camapp_handle is NULL");
315
316 /*mm stop rec */
317         if (!cam_mm_rec_cancel(NULL)) {
318                 cam_critical(LOG_MM, "cam_mm_rec_cancel failed");
319         }
320
321         /* change to camera mode*/
322                 /*
323                 *       TODO: if for any reason, not run here, there will be caused now now recording, but in record mode
324                 *       So: I suggest while click capture button: judge now state and whether recording.
325                 */
326
327         if(ad->launching_mode == CAM_LAUNCHING_MODE_NORMAL) {
328                 if (ad->ug_state != CAM_UG_PAUSE_STATE) {/*if now is pause state, so do not set mode, just set while resume*/
329
330                         GValue value = {0, };
331                         CAM_GVALUE_SET_INT(value, CAM_CAMERA_MODE);
332                         if (!cam_handle_value_set(ad, PROP_MODE, &value)) {
333                                 return FALSE;
334                         }
335
336                         cam_app_update_quickview_icon(ad);
337                 }
338         }
339
340         unload_recording_edje(ad);
341         camapp->rec_elapsed = 0;
342         cam_toolbar_update(ad);
343
344         if (ad->indicator_edje)
345                 cam_indicator_update(ad);
346         else
347                 cam_indicator_create(ad);
348
349         settings_guideline_refresh(ad);
350         cam_remove_tmp_file();
351         return TRUE;
352 }
353
354 /* Idler of capture callback management. wh01.cho@samsung.com. 2010-12-15. */
355 Eina_Bool cam_video_capture_handle_idler(void *itm)
356 {
357         CamIdlerItem *item = (CamIdlerItem *) itm;
358         struct appdata *ad = NULL;
359         cam_retvm_if(!item, ECORE_CALLBACK_CANCEL, "CamIdlerItem is NULL");
360
361         ad = (struct appdata *)item->data;
362         cam_retvm_if(!ad, ECORE_CALLBACK_CANCEL, "appdata is NULL");
363
364         ad->capture_cb_list = g_list_remove(ad->capture_cb_list, item->idler);
365         free(item);
366         item = NULL;
367
368         return cam_video_capture_handle(ad);
369 }
370
371 gboolean cam_rec_save_and_register_video_file(void *data)
372 {
373         struct appdata *ad = (struct appdata *)data;
374         CamAppData *camapp = NULL;
375         cam_retvm_if(ad == NULL, FALSE, "appdata is NULL");
376         camapp = ad->camapp_handle;
377         cam_retvm_if(camapp == NULL, FALSE, "camapp_handle is NULL");
378         cam_retv_if(camapp->filename == NULL, FALSE);
379
380         GError *error = NULL;
381         cam_debug(LOG_FILE, "tmp file : %s", camapp->filename);
382
383         gchar *filename = NULL;
384         filename = cam_app_get_next_filename(CAM_FILE_EXTENTION_VIDEO);
385
386         if (filename) {
387                 cam_debug(LOG_UI, "FILE NAME : %s", filename);
388
389                 int ret = 0;
390
391                 ret = rename(camapp->filename, filename);
392
393                 if( ret != 0)
394                         cam_critical(LOG_FILE, "rename is error %d", ret );
395
396                 sync();
397                 free(camapp->filename);
398                 camapp->filename = strdup(filename);
399
400                 free(filename);
401                 filename = NULL;
402
403                 if (!g_file_test(camapp->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
404                         cam_critical(LOG_FILE, "The File is not existed %s",camapp->filename );
405                         return ECORE_CALLBACK_CANCEL;
406                 }
407         } else {
408                 cam_critical(LOG_MM, "cannot get filename");
409                 return ECORE_CALLBACK_CANCEL;
410         }
411         if (!cam_file_register(camapp->filename, &error)) {
412                 cam_critical(LOG_FILE, "cam_file_register fail");
413                 if (error != NULL) {
414                         cam_critical(LOG_FILE,
415                                      "cam_file_register error [%s]",
416                                      error->message);
417                         g_error_free(error);
418                         error = NULL;
419                 }
420         }
421         if (ad->launching_mode == CAM_LAUNCHING_MODE_NORMAL)
422                 cam_app_update_thumbnail();
423
424         /*TODO: use pipe*/
425         if (camapp->review) {
426                 DEBUG_TRACE(" review on in recording mode");
427                 cam_utils_request_main_pipe_handler(ad, NULL, CAM_MAIN_PIPE_OP_TYPE_RUN_IMAGE_VIEWER);
428         }
429         return TRUE;
430 }
431
432 Eina_Bool cam_video_capture_handle(void *data)
433 {
434         struct appdata *ad = (struct appdata *)data;
435         CamAppData *camapp = NULL;
436
437                 /* set recording state */
438         ad->is_recording = FALSE;
439
440         cam_retvm_if(ad == NULL, ECORE_CALLBACK_CANCEL, "appdata is NULL");
441         camapp = ad->camapp_handle;
442         cam_retvm_if(camapp == NULL, ECORE_CALLBACK_CANCEL,
443                      "camapp_handle is NULL");
444
445         cam_debug(LOG_FILE, "");
446
447         camapp->rec_elapsed = 0;
448         SHOW_EVAS_OBJECT(ad->indicator_edje);
449         unload_recording_edje(ad);
450         camapp->rec_elapsed = 0;
451         cam_toolbar_update(ad);
452         if (ad->indicator_edje)
453                 cam_indicator_update(ad);
454         else
455                 cam_indicator_create(ad);
456         settings_guideline_refresh(ad);
457
458         if (camapp->filename) {
459                 ad->remained_count--;
460                 indicator_update_remain_count(ad);
461         }
462         g_queue_push_tail(ad->file_reg_queue, strdup(REC_FILE_SAVE_REG));
463         pthread_cond_signal(&ad->file_reg_cond);
464
465         switch (camapp->rec_stop_type) {
466         case CAM_REC_STOP_UNEXPECTED:
467                 break;
468         case CAM_REC_STOP_NORMAL:
469                 break;
470         case CAM_REC_STOP_LOW_BATTERY:
471                 cam_app_exit(ad);
472                 return ECORE_CALLBACK_CANCEL;
473                 break;
474         case CAM_REC_STOP_ASM:
475                 break;
476         case CAM_REC_STOP_MAX_SIZE:
477                 break;
478         case CAM_REC_STOP_TIME_LIMIT:
479                 break;
480         case CAM_REC_STOP_NO_SPACE:
481                 cam_app_notice_popup(ad, dgettext(PACKAGE, "IDS_CAM_POP_VIDEOMEMORYFULL"),
482                                      cam_app_popup_response_cb);
483                 break;
484         case CAM_REC_STOP_USB_CONN:
485                 break;
486         case CAM_REC_STOP_POWER_KEY:
487                 power_unlock_state(POWER_STATE_NORMAL);
488                 break;
489         default:
490                 break;
491         }
492         camapp->rec_stop_type = CAM_REC_STOP_UNEXPECTED;
493
494         return ECORE_CALLBACK_CANCEL;
495 }