Improve PP(PredefinedPreprocessor) score
[platform/core/api/recorder.git] / src / recorder.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <inttypes.h>
21 #include <camera_internal.h>
22 #include <recorder.h>
23 #include <sound_manager.h>
24 #include <sound_manager_internal.h>
25 #include <storage.h>
26 #include <storage-internal.h>
27 #include <muse_recorder.h>
28 #include <muse_recorder_msg.h>
29 #include <muse_core.h>
30 #include <muse_client.h>
31 #include <recorder_private.h>
32 #include <gio/gio.h>
33 #include <dlog.h>
34 #include <tzplatform_config.h>
35
36 #define MODULE_NAME     "recorder"
37
38
39 /* for device changed callback */
40 static GMutex g_rec_dev_state_changed_cb_lock;
41 static GList *g_rec_dev_state_changed_cb_list;
42 static int g_rec_dev_state_changed_cb_id;
43 static GDBusConnection *g_rec_dev_state_changed_cb_conn;
44 static guint g_rec_dev_state_changed_cb_subscribe_id;
45 static GMutex g_rec_idle_event_lock;
46
47 /* log level */
48 static int g_recorder_log_level;
49
50
51 static void __recorder_update_api_waiting(recorder_cb_info_s *cb_info, int api, int value)
52 {
53         if (!cb_info ||
54                 api < 0 || api >= MUSE_RECORDER_API_MAX) {
55                 REC_LOG_ERROR("invalid param[%p][%d]", cb_info, api);
56                 return;
57         }
58
59         g_mutex_lock(&(cb_info->api_mutex[api]));
60         cb_info->api_waiting[api] += value;
61         g_mutex_unlock(&(cb_info->api_mutex[api]));
62
63         REC_LOG_DEBUG("api[%d], value[%d], waiting[%d]",
64                 api, value, cb_info->api_waiting[api]);
65
66         return;
67 }
68
69
70 static void __recorder_device_state_changed_cb(GDBusConnection *connection,
71         const gchar *sender_name, const gchar *object_path, const gchar *interface_name,
72         const gchar *signal_name, GVariant *param, gpointer user_data)
73 {
74         int value = 0;
75         recorder_type_e type = RECORDER_TYPE_AUDIO;
76         recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
77         GList *tmp_list = NULL;
78         recorder_cb_info *info = NULL;
79
80         g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
81
82         if (!g_rec_dev_state_changed_cb_list || !param) {
83                 REC_LOG_WARNING("no callback or NULL param[%p]", param);
84                 goto _DONE;
85         }
86
87         /* get device type and state */
88         g_variant_get(param, "(i)", &value);
89
90         type = value >> 16;
91         state = 0x0000ffff & value;
92
93         REC_LOG_INFO("type[%d], state[%d]", type, state);
94
95         tmp_list = g_rec_dev_state_changed_cb_list;
96
97         do {
98                 info = (recorder_cb_info *)tmp_list->data;
99
100                 if (info) {
101                         if (info->callback) {
102                                 REC_LOG_INFO("start id[%d] callback", info->id);
103                                 ((recorder_device_state_changed_cb)info->callback)(type, state, info->user_data);
104                                 REC_LOG_INFO("returned id[%d] callback", info->id);
105                         } else {
106                                 REC_LOG_WARNING("NULL callback for id[%d]", info->id);
107                         }
108                 }
109
110                 tmp_list = tmp_list->next;
111         } while (tmp_list);
112
113 _DONE:
114         g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
115
116         return;
117 }
118
119
120 static int _recorder_import_tbm_fd(tbm_bufmgr bufmgr, int fd, tbm_bo *bo, tbm_bo_handle *bo_handle)
121 {
122         tbm_bo tmp_bo = NULL;
123         tbm_bo_handle tmp_bo_handle = {NULL, };
124
125         if (bufmgr == NULL || bo == NULL || bo_handle == NULL || fd < 0) {
126                 REC_LOG_ERROR("invalid parameter - bufmgr[%p], bo[%p], bo_handle[%p], fd[%d]",
127                      bufmgr, bo, bo_handle, fd);
128                 return false;
129         }
130
131         tmp_bo = tbm_bo_import_fd(bufmgr, (tbm_fd)fd);
132         if (tmp_bo == NULL) {
133                 REC_LOG_ERROR("bo import failed - bufmgr[%p], fd[%d]", bufmgr, fd);
134                 return false;
135         }
136
137         tmp_bo_handle = tbm_bo_map(tmp_bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
138         if (tmp_bo_handle.ptr == NULL) {
139                 REC_LOG_ERROR("bo map failed[%p]", tmp_bo);
140                 tbm_bo_unref(tmp_bo);
141                 tmp_bo = NULL;
142                 return false;
143         }
144
145         /* set bo and bo_handle */
146         *bo = tmp_bo;
147         *bo_handle = tmp_bo_handle;
148
149         REC_LOG_VERBOSE("import fd[%d] -> bo[%p]", fd, tmp_bo);
150
151         return true;
152 }
153
154 static void _recorder_release_imported_bo(tbm_bo *bo)
155 {
156         if (bo == NULL || *bo == NULL) {
157                 REC_LOG_WARNING("NULL bo");
158                 return;
159         }
160
161         REC_LOG_VERBOSE("release bo[%p]", *bo);
162
163         tbm_bo_unmap(*bo);
164         tbm_bo_unref(*bo);
165         *bo = NULL;
166
167         return;
168 }
169
170 static void _recorder_event_handler_video_encode_decision(recorder_cb_info_s *cb_info, char *recv_msg, int *tfd)
171 {
172         int i = 0;
173         int event = MUSE_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION;
174         int video_fd = -1;
175         int num_buffer_fd = 0;
176         bool do_encode = true;
177
178         tbm_bo bo = NULL;
179         tbm_bo buffer_bo[BUFFER_MAX_PLANE_NUM] = {NULL, };
180         tbm_bo_handle bo_handle = {.ptr = NULL};
181         tbm_bo_handle buffer_bo_handle[BUFFER_MAX_PLANE_NUM] = {{.ptr = NULL}, };
182         tbm_bo data_bo = NULL;
183         tbm_bo_handle data_bo_handle = {.ptr = NULL};
184
185         recorder_video_data_s frame;
186         MMCamcorderVideoStreamDataType *stream = NULL;
187
188         char *send_msg = NULL;
189
190         /* tfd[0]: MMCamcorderVideoStreamDataType
191            tfd[1]: data_bo or zero copy bo[0]
192            tfd[2]: zero copy bo[1]
193            tfd[3]: zero copy bo[2] */
194         if (!tfd || tfd[0] < 0) {
195                 REC_LOG_ERROR("invalid fd[%d]", tfd ? tfd[0] : 0);
196                 return;
197         }
198
199         muse_recorder_msg_get(video_fd, recv_msg);
200         muse_recorder_msg_get(num_buffer_fd, recv_msg);
201
202         REC_LOG_DEBUG("video_fd[%d], num_buffer_fd[%d], tfd[%d/%d/%d/%d]",
203                 video_fd, num_buffer_fd, tfd[0], tfd[1], tfd[2], tfd[3]);
204
205         memset(&frame, 0x0, sizeof(recorder_video_data_s));
206
207         if (num_buffer_fd < 0 || num_buffer_fd > BUFFER_MAX_PLANE_NUM) {
208                 REC_LOG_ERROR("invalid num buffer fd[%d]", num_buffer_fd);
209                 goto _VIDEO_ENCODE_DECISION_CB_HANDLER_DONE;
210         }
211
212         /* import tbm bo and get virtual address */
213         if (!_recorder_import_tbm_fd(cb_info->bufmgr, tfd[0], &bo, &bo_handle)) {
214                 REC_LOG_ERROR("failed to import fd[%d]", tfd[0]);
215                 goto _VIDEO_ENCODE_DECISION_CB_HANDLER_DONE;
216         }
217
218         if (num_buffer_fd == 0 && tfd[1] >= 0) {
219                 /* import tbm data_bo and get virtual address */
220                 if (!_recorder_import_tbm_fd(cb_info->bufmgr, tfd[1], &data_bo, &data_bo_handle)) {
221                         REC_LOG_ERROR("failed to import data fd[%d]", tfd[1]);
222                         goto _VIDEO_ENCODE_DECISION_CB_HANDLER_DONE;
223                 }
224         }
225
226         /* get stream info */
227         stream = (MMCamcorderVideoStreamDataType *)bo_handle.ptr;
228
229         for (i = 0 ; i < num_buffer_fd ; i++) {
230                 /* import buffer bo and get virtual address */
231                 if (!_recorder_import_tbm_fd(cb_info->bufmgr, tfd[i + 1], &buffer_bo[i], &buffer_bo_handle[i])) {
232                         REC_LOG_ERROR("failed to import buffer fd[%d]", tfd[i + 1]);
233                         goto _VIDEO_ENCODE_DECISION_CB_HANDLER_DONE;
234                 }
235         }
236
237         if (cb_info->user_cb[event]) {
238                 camera_create_preview_frame(stream, num_buffer_fd, buffer_bo_handle, &data_bo_handle, &frame);
239                 do_encode = ((recorder_video_encode_decision_cb)cb_info->user_cb[event])(&frame, cb_info->user_data[event]);
240         }
241
242 _VIDEO_ENCODE_DECISION_CB_HANDLER_DONE:
243         /* return buffer */
244         send_msg = muse_core_msg_new(MUSE_RECORDER_API_RETURN_BUFFER,
245                 MUSE_TYPE_INT, "ret_fd", video_fd,
246                 MUSE_TYPE_INT, "buffer_type", MUSE_RECORDER_BUFFER_TYPE_VIDEO_ENCODE_DECISION,
247                 MUSE_TYPE_INT, "video_encode_decision", (int)do_encode,
248                 NULL);
249         if (send_msg) {
250                 if (muse_core_msg_send(cb_info->fd, send_msg) <= 0)
251                         REC_LOG_ERROR("sending message failed");
252
253                 muse_core_msg_free(send_msg);
254                 send_msg = NULL;
255         } else {
256                 REC_LOG_ERROR("failed to create send msg for fd[%d]", tfd[0]);
257         }
258
259         /* release imported bo and fd */
260         for (i = 0 ; i < num_buffer_fd && i < BUFFER_MAX_PLANE_NUM ; i++)
261                 _recorder_release_imported_bo(&buffer_bo[i]);
262
263         /* unmap and unref tbm bo */
264         if (data_bo)
265                 _recorder_release_imported_bo(&data_bo);
266         if (bo)
267                 _recorder_release_imported_bo(&bo);
268
269         /* close imported fd */
270         for (i = 0 ; i < MUSE_NUM_FD ; i++) {
271                 if (tfd[i] >= 0) {
272                         close(tfd[i]);
273                         tfd[i] = -1;
274                 } else {
275                         break;
276                 }
277         }
278 }
279
280 static void _recorder_client_user_callback(recorder_cb_info_s *cb_info, char *recv_msg, muse_recorder_event_e event, int *tfd)
281 {
282         if (recv_msg == NULL || event >= MUSE_RECORDER_EVENT_TYPE_NUM) {
283                 REC_LOG_ERROR("invalid parameter - recorder msg[%p], event[%d]", recv_msg, event);
284                 return;
285         }
286
287         REC_LOG_DEBUG("get recorder msg[%s], event[%d]", recv_msg, event);
288
289         g_mutex_lock(&cb_info->user_cb_mutex[event]);
290
291         if (cb_info->user_cb[event] == NULL) {
292                 if (event != MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM &&
293                         event != MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM &&
294                         event != MUSE_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION) {
295                         g_mutex_unlock(&cb_info->user_cb_mutex[event]);
296                         REC_LOG_WARNING("NULL callback for event[%d], return here", event);
297                         return;
298                 } else {
299                         REC_LOG_WARNING("NULL callback for event[%d], NOT return here", event);
300                 }
301         }
302
303         switch (event) {
304         case MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE:
305                 {
306                         int previous = 0;
307                         int current = 0;
308                         int by_policy = 0;
309
310                         muse_recorder_msg_get(previous, recv_msg);
311                         muse_recorder_msg_get(current, recv_msg);
312                         muse_recorder_msg_get(by_policy, recv_msg);
313
314                         ((recorder_state_changed_cb)cb_info->user_cb[event])((recorder_state_e)previous,
315                                 (recorder_state_e)current,
316                                 (bool)by_policy,
317                                 cb_info->user_data[event]);
318                         break;
319                 }
320         case MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED:
321                 {
322                         int type = 0;
323
324                         muse_recorder_msg_get(type, recv_msg);
325
326                         ((recorder_recording_limit_reached_cb)cb_info->user_cb[event])((recorder_recording_limit_type_e)type,
327                                 cb_info->user_data[event]);
328                         break;
329                 }
330         case MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS:
331                 {
332                         int64_t cb_elapsed_time = 0;
333                         int64_t cb_file_size = 0;
334
335                         muse_recorder_msg_get_int64(cb_elapsed_time, recv_msg);
336                         muse_recorder_msg_get_int64(cb_file_size, recv_msg);
337
338                         ((recorder_recording_status_cb)cb_info->user_cb[event])((unsigned long long)cb_elapsed_time,
339                                 (unsigned long long)cb_file_size,
340                                 cb_info->user_data[event]);
341                         break;
342                 }
343         case MUSE_RECORDER_EVENT_TYPE_INTERRUPTED:
344                 {
345                         int policy = 0;
346                         int previous = 0;
347                         int current = 0;
348
349                         muse_recorder_msg_get(policy, recv_msg);
350                         muse_recorder_msg_get(previous, recv_msg);
351                         muse_recorder_msg_get(current, recv_msg);
352
353                         REC_LOG_WARNING("INTERRUPTED - policy[%d], state[%d] ->[%d]", policy, previous, current);
354
355                         ((recorder_interrupted_cb)cb_info->user_cb[event])((recorder_policy_e)policy,
356                                 (recorder_state_e)previous,
357                                 (recorder_state_e)current,
358                                 cb_info->user_data[event]);
359                         break;
360                 }
361         case MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED:
362                 {
363                         int policy = 0;
364                         int state = 0;
365
366                         muse_recorder_msg_get(policy, recv_msg);
367                         muse_recorder_msg_get(state, recv_msg);
368
369                         REC_LOG_WARNING("INTERRUPT_STARTED - policy[%d], state[%d]", policy, state);
370
371                         ((recorder_interrupt_started_cb)cb_info->user_cb[event])((recorder_policy_e)policy,
372                                 (recorder_state_e)state, cb_info->user_data[event]);
373                 }
374                 break;
375         case MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM:
376                 {
377                         int audio_fd = -1;
378                         int size = 0;
379                         int format = 0;
380                         int channel = 0;
381                         int timestamp = 0;
382                         tbm_bo bo = NULL;
383                         tbm_bo_handle bo_handle = {.ptr = NULL};
384                         char *send_msg = NULL;
385
386                         if (!tfd || tfd[0] < 0) {
387                                 REC_LOG_ERROR("invalid fd[%d]", tfd ? tfd[0] : 0);
388                                 break;
389                         }
390
391                         muse_recorder_msg_get(audio_fd, recv_msg);
392
393                         if (cb_info->user_cb[event]) {
394                                 if (_recorder_import_tbm_fd(cb_info->bufmgr, tfd[0], &bo, &bo_handle)) {
395                                         muse_recorder_msg_get(size, recv_msg);
396                                         muse_recorder_msg_get(format, recv_msg);
397                                         muse_recorder_msg_get(channel, recv_msg);
398                                         muse_recorder_msg_get(timestamp, recv_msg);
399
400                                         REC_LOG_DEBUG("size[%d], format[%d], channel[%d], timestamp[%d]",
401                                                 size, format, channel, timestamp);
402
403                                         ((recorder_audio_stream_cb)cb_info->user_cb[event])((void *)bo_handle.ptr,
404                                                 size, (audio_sample_type_e)format, channel,
405                                                 (unsigned int)timestamp, cb_info->user_data[event]);
406
407                                         REC_LOG_VERBOSE("returned");
408
409                                         /* release imported bo */
410                                         _recorder_release_imported_bo(&bo);
411                                 } else {
412                                         REC_LOG_ERROR("tbm fd[%d] import failed", tfd[0]);
413                                 }
414                         }
415
416                         /* return buffer */
417                         send_msg = muse_core_msg_new(MUSE_RECORDER_API_RETURN_BUFFER,
418                                 MUSE_TYPE_INT, "ret_fd", audio_fd,
419                                 MUSE_TYPE_INT, "buffer_type", MUSE_RECORDER_BUFFER_TYPE_AUDIO_STREAM,
420                                 NULL);
421                         if (send_msg) {
422                                 if (muse_core_msg_send(cb_info->fd, send_msg) <= 0)
423                                         REC_LOG_ERROR("sending message failed");
424
425                                 muse_core_msg_free(send_msg);
426                                 send_msg = NULL;
427                         } else {
428                                 REC_LOG_ERROR("failed to create send msg for fd[%d]", audio_fd);
429                         }
430
431                         /* close imported fd */
432                         close(tfd[0]);
433                         tfd[0] = -1;
434                         break;
435                 }
436         case MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM:
437                 {
438                         int muxed_fd = -1;
439                         int size = 0;
440                         int64_t offset = 0;
441
442                         tbm_bo bo = NULL;
443                         tbm_bo_handle bo_handle = {.ptr = NULL};
444                         char *send_msg = NULL;
445
446                         if (!tfd || tfd[0] < 0) {
447                                 REC_LOG_ERROR("invalid fd[%d]", tfd ? tfd[0] : 0);
448                                 break;
449                         }
450
451                         muse_recorder_msg_get(muxed_fd, recv_msg);
452
453                         if (cb_info->user_cb[event]) {
454                                 if (_recorder_import_tbm_fd(cb_info->bufmgr, tfd[0], &bo, &bo_handle)) {
455                                         muse_recorder_msg_get(size, recv_msg);
456                                         muse_recorder_msg_get_int64(offset, recv_msg);
457
458                                         REC_LOG_DEBUG("size[%d], offset[%"PRId64"]", size, offset);
459
460                                         ((recorder_muxed_stream_cb)cb_info->user_cb[event])((void *)bo_handle.ptr,
461                                                 size, (unsigned long long)offset, cb_info->user_data[event]);
462
463                                         REC_LOG_VERBOSE("returned");
464
465                                         /* release imported bo */
466                                         _recorder_release_imported_bo(&bo);
467                                 } else {
468                                         REC_LOG_ERROR("tbm fd[%d] import failed", tfd[0]);
469                                 }
470                         }
471
472                         /* return buffer */
473                         send_msg = muse_core_msg_new(MUSE_RECORDER_API_RETURN_BUFFER,
474                                 MUSE_TYPE_INT, "ret_fd", muxed_fd,
475                                 MUSE_TYPE_INT, "buffer_type", MUSE_RECORDER_BUFFER_TYPE_MUXED_STREAM,
476                                 NULL);
477                         if (send_msg) {
478                                 if (muse_core_msg_send(cb_info->fd, send_msg) <= 0)
479                                         REC_LOG_ERROR("sending message failed");
480
481                                 muse_core_msg_free(send_msg);
482                                 send_msg = NULL;
483                         } else {
484                                 REC_LOG_ERROR("failed to create send msg for fd[%d]", tfd[0]);
485                         }
486
487                         /* close imported fd */
488                         close(tfd[0]);
489                         tfd[0] = -1;
490                         break;
491                 }
492         case MUSE_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION:
493                 _recorder_event_handler_video_encode_decision(cb_info, recv_msg, tfd);
494                 break;
495 //LCOV_EXCL_START
496         case MUSE_RECORDER_EVENT_TYPE_ERROR:
497                 {
498                         int error = 0;
499                         int current_state = 0;
500
501                         muse_recorder_msg_get(error, recv_msg);
502                         muse_recorder_msg_get(current_state, recv_msg);
503
504                         ((recorder_error_cb)cb_info->user_cb[event])((recorder_error_e)error,
505                                 (recorder_state_e)current_state,
506                                 cb_info->user_data[event]);
507                         break;
508                 }
509 //LCOV_EXCL_STOP
510         case MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_AUDIO_ENCODER:
511                 {
512                         int codec = 0;
513
514                         muse_recorder_msg_get(codec, recv_msg);
515
516                         if (((recorder_supported_audio_encoder_cb)cb_info->user_cb[event])((recorder_audio_codec_e)codec, cb_info->user_data[event]) == false) {
517                                 cb_info->user_cb[event] = NULL;
518                                 cb_info->user_data[event] = NULL;
519                                 REC_LOG_DEBUG("stop foreach callback for SUPPORTED_AUDIO_ENCODER");
520                         }
521                         break;
522                 }
523         case MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_FILE_FORMAT:
524                 {
525                         int format = 0;
526
527                         muse_recorder_msg_get(format, recv_msg);
528
529                         if (((recorder_supported_file_format_cb)cb_info->user_cb[event])((recorder_file_format_e)format, cb_info->user_data[event]) == false) {
530                                 cb_info->user_cb[event] = NULL;
531                                 cb_info->user_data[event] = NULL;
532                                 REC_LOG_DEBUG("stop foreach callback for SUPPORTED_FILE_FORMAT");
533                         }
534                         break;
535                 }
536         case MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_ENCODER:
537                 {
538                         int codec = 0;
539
540                         muse_recorder_msg_get(codec, recv_msg);
541
542                         if (((recorder_supported_video_encoder_cb)cb_info->user_cb[event])((recorder_video_codec_e)codec, cb_info->user_data[event]) == false) {
543                                 cb_info->user_cb[event] = NULL;
544                                 cb_info->user_data[event] = NULL;
545                                 REC_LOG_DEBUG("stop foreach callback for SUPPORTED_VIDEO_ENCODER");
546                         }
547                         break;
548                 }
549         default: /* MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_RESOLUTION */
550                 {
551                         int width = 0;
552                         int height = 0;
553
554                         muse_recorder_msg_get(width, recv_msg);
555                         muse_recorder_msg_get(height, recv_msg);
556
557                         if (((recorder_supported_video_resolution_cb)cb_info->user_cb[event])(width, height, cb_info->user_data[event]) == false) {
558                                 cb_info->user_cb[event] = NULL;
559                                 cb_info->user_data[event] = NULL;
560                                 REC_LOG_DEBUG("stop foreach callback for SUPPORTED_VIDEO_RESOLUTION");
561                         }
562                         break;
563                 }
564         }
565
566         g_mutex_unlock(&cb_info->user_cb_mutex[event]);
567
568         return;
569 }
570
571
572 static gboolean _recorder_idle_event_callback(gpointer data)
573 {
574         recorder_cb_info_s *cb_info = NULL;
575         recorder_idle_event_s *rec_idle_event = (recorder_idle_event_s *)data;
576
577         if (rec_idle_event == NULL) {
578                 REC_LOG_ERROR("rec_idle_event is NULL");
579                 return FALSE;
580         }
581
582         /* lock event */
583         g_mutex_lock(&g_rec_idle_event_lock);
584
585         cb_info = rec_idle_event->cb_info;
586         if (cb_info == NULL) {
587                 REC_LOG_WARNING("recorder cb_info is NULL. event[%p][%d]", rec_idle_event, rec_idle_event->event);
588                 g_mutex_unlock(&g_rec_idle_event_lock);
589                 goto IDLE_EVENT_CALLBACK_DONE;
590         }
591
592         /* remove event from list */
593         if (cb_info->idle_event_list)
594                 cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)rec_idle_event);
595
596         g_mutex_unlock(&g_rec_idle_event_lock);
597
598         /* user callback */
599         _recorder_client_user_callback(cb_info, rec_idle_event->recv_msg, rec_idle_event->event, NULL);
600
601 IDLE_EVENT_CALLBACK_DONE:
602         /* release event */
603         g_free(rec_idle_event);
604         rec_idle_event = NULL;
605
606         return FALSE;
607 }
608
609
610 static void _recorder_deactivate_idle_event_all(recorder_cb_info_s *cb_info)
611 {
612         recorder_idle_event_s *rec_idle_event = NULL;
613         GList *list = NULL;
614
615         if (cb_info == NULL) {
616                 REC_LOG_ERROR("cb_info is NULL");
617                 return;
618         }
619
620         g_mutex_lock(&g_rec_idle_event_lock);
621
622         if (cb_info->idle_event_list == NULL) {
623                 REC_LOG_INFO("No event");
624         } else {
625                 list = cb_info->idle_event_list;
626
627                 while (list) {
628                         rec_idle_event = list->data;
629                         list = g_list_next(list);
630
631                         if (!rec_idle_event) {
632                                 REC_LOG_WARNING("The event is NULL");
633                                 continue;
634                         }
635
636                         if (g_idle_remove_by_data(rec_idle_event)) {
637                                 REC_LOG_WARNING("remove idle event[%p] done", rec_idle_event);
638
639                                 cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)rec_idle_event);
640
641                                 g_free(rec_idle_event);
642                                 rec_idle_event = NULL;
643
644                                 continue;
645                         }
646
647                         REC_LOG_WARNING("set NULL cb_info for event[%p][%d], it will be freed on idle callback",
648                                 rec_idle_event, rec_idle_event->event);
649
650                         rec_idle_event->cb_info = NULL;
651
652                         cb_info->idle_event_list = g_list_remove(cb_info->idle_event_list, (gpointer)rec_idle_event);
653                 }
654
655                 g_list_free(cb_info->idle_event_list);
656                 cb_info->idle_event_list = NULL;
657         }
658
659         g_mutex_unlock(&g_rec_idle_event_lock);
660
661         return;
662 }
663
664
665 static void __recorder_add_msg_to_queue(recorder_cb_info_s *cb_info, int api, int event, int event_class, char *msg, int *tfd)
666 {
667         recorder_message_s *rec_msg = NULL;
668         recorder_msg_handler_info_s *msg_handler_info = NULL;
669
670         if (!cb_info || !msg) {
671                 REC_LOG_ERROR("NULL pointer[%p][%p]", cb_info, msg);
672                 return;
673         }
674
675         rec_msg = g_new0(recorder_message_s, 1);
676         if (!rec_msg) {
677                 REC_LOG_ERROR("failed to alloc rec_msg for[%s]", msg);
678                 return;
679         }
680
681         rec_msg->api = api;
682         rec_msg->event = event;
683         rec_msg->event_class = event_class;
684
685         if (tfd && tfd[0] >= 0)
686                 memcpy(rec_msg->tfd, tfd, sizeof(rec_msg->tfd));
687
688         strncpy(rec_msg->recv_msg, msg, sizeof(rec_msg->recv_msg) - 1);
689
690         REC_LOG_DEBUG("api[%d], event[%d], event_class[%d]",
691                 api, event, event_class);
692
693         if (event == MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM)
694                 msg_handler_info = &cb_info->audio_stream_cb_info;
695         else if (event == MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM)
696                 msg_handler_info = &cb_info->muxed_stream_cb_info;
697         else
698                 msg_handler_info = &cb_info->msg_handler_info;
699
700         g_mutex_lock(&msg_handler_info->mutex);
701         g_queue_push_tail(msg_handler_info->queue, (gpointer)rec_msg);
702         g_cond_signal(&msg_handler_info->cond);
703         g_mutex_unlock(&msg_handler_info->mutex);
704
705         rec_msg = NULL;
706
707         return;
708 }
709
710
711 static void __recorder_get_api_operation(int api, recorder_cb_info_s *cb_info, char *msg)
712 {
713         if (!cb_info || !msg) {
714                 REC_LOG_ERROR("NULL pointer[%p][%p]", cb_info, msg);
715                 return;
716         }
717
718         switch (api) {
719         case MUSE_RECORDER_API_GET_STATE:
720                 {
721                         int get_state = 0;
722                         muse_recorder_msg_get(get_state, msg);
723                         cb_info->get_int_value[_RECORDER_GET_INT_STATE] = get_state;
724                 }
725                 break;
726         case MUSE_RECORDER_API_GET_VIDEO_RESOLUTION:
727                 {
728                         int get_width = 0;
729                         int get_height = 0;
730                         muse_recorder_msg_get(get_width, msg);
731                         muse_recorder_msg_get(get_height, msg);
732                         cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_RESOLUTION] = get_width << 16;
733                         cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_RESOLUTION] |= get_height;
734                 }
735                 break;
736         case MUSE_RECORDER_API_GET_FILE_FORMAT:
737                 {
738                         int get_format = 0;
739                         muse_recorder_msg_get(get_format, msg);
740                         cb_info->get_int_value[_RECORDER_GET_INT_FILE_FORMAT] = get_format;
741                 }
742                 break;
743         case MUSE_RECORDER_API_GET_AUDIO_ENCODER:
744                 {
745                         int get_codec = 0;
746                         muse_recorder_msg_get(get_codec, msg);
747                         cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_ENCODER] = get_codec;
748                 }
749                 break;
750         case MUSE_RECORDER_API_GET_VIDEO_ENCODER:
751                 {
752                         int get_codec = 0;
753                         muse_recorder_msg_get(get_codec, msg);
754                         cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_ENCODER] = get_codec;
755                 }
756                 break;
757         case MUSE_RECORDER_API_ATTR_GET_SIZE_LIMIT:
758                 {
759                         int get_kbyte = 0;
760                         muse_recorder_msg_get(get_kbyte, msg);
761                         cb_info->get_int_value[_RECORDER_GET_INT_SIZE_LIMIT] = get_kbyte;
762                 }
763                 break;
764         case MUSE_RECORDER_API_ATTR_GET_TIME_LIMIT:
765                 {
766                         int get_second = 0;
767                         muse_recorder_msg_get(get_second, msg);
768                         cb_info->get_int_value[_RECORDER_GET_INT_TIME_LIMIT] = get_second;
769                 }
770                 break;
771         case MUSE_RECORDER_API_ATTR_GET_AUDIO_DEVICE:
772                 {
773                         int get_device = 0;
774                         muse_recorder_msg_get(get_device, msg);
775                         cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_DEVICE] = get_device;
776                 }
777                 break;
778         case MUSE_RECORDER_API_ATTR_GET_AUDIO_SAMPLERATE:
779                 {
780                         int get_samplerate = 0;
781                         muse_recorder_msg_get(get_samplerate, msg);
782                         cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_SAMPLERATE] = get_samplerate;
783                 }
784                 break;
785         case MUSE_RECORDER_API_ATTR_GET_AUDIO_ENCODER_BITRATE:
786                 {
787                         int get_bitrate = 0;
788                         muse_recorder_msg_get(get_bitrate, msg);
789                         cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_ENCODER_BITRATE] = get_bitrate;
790                 }
791                 break;
792         case MUSE_RECORDER_API_ATTR_GET_VIDEO_ENCODER_BITRATE:
793                 {
794                         int get_bitrate = 0;
795                         muse_recorder_msg_get(get_bitrate, msg);
796                         cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_ENCODER_BITRATE] = get_bitrate;
797                 }
798                 break;
799         case MUSE_RECORDER_API_ATTR_GET_RECORDING_MOTION_RATE:
800                 {
801                         double get_rate = 0;
802                         muse_recorder_msg_get_double(get_rate, msg);
803                         cb_info->get_double_value[_RECORDER_GET_DOUBLE_RECORDING_MOTION_RATE] = get_rate;
804                 }
805                 break;
806         case MUSE_RECORDER_API_ATTR_GET_AUDIO_CHANNEL:
807                 {
808                         int get_channel_count = 0;
809                         muse_recorder_msg_get(get_channel_count, msg);
810                         cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_CHANNEL] = get_channel_count;
811                 }
812                 break;
813         case MUSE_RECORDER_API_ATTR_GET_ORIENTATION_TAG:
814                 {
815                         int get_orientation = 0;
816                         muse_recorder_msg_get(get_orientation, msg);
817                         cb_info->get_int_value[_RECORDER_GET_INT_ORIENTATION_TAG] = get_orientation;
818                 }
819                 break;
820         case MUSE_RECORDER_API_GET_AUDIO_LEVEL:
821                 {
822                         double get_level = 0.0;
823                         muse_recorder_msg_get_double(get_level, msg);
824                         cb_info->get_double_value[_RECORDER_GET_DOUBLE_AUDIO_LEVEL] = get_level;
825                 }
826                 break;
827         case MUSE_RECORDER_API_GET_FILENAME:
828                 {
829                         char get_filename[MUSE_RECORDER_MSG_MAX_LENGTH] = {'\0',};
830                         muse_recorder_msg_get_string(get_filename, msg);
831                         if (cb_info->get_filename) {
832                                 free(cb_info->get_filename);
833                                 cb_info->get_filename = NULL;
834                         }
835                         cb_info->get_filename = strdup(get_filename);
836                 }
837                 break;
838         default:
839                 break;
840         }
841
842         return;
843 }
844
845
846 static void __recorder_process_msg(recorder_cb_info_s *cb_info, char *msg, int *tfd)
847 {
848         int ret = RECORDER_ERROR_NONE;
849         int api = -1;
850         int api_class = -1;
851         int event = -1;
852         int event_class = -1;
853
854         if (!cb_info || !msg) {
855                 REC_LOG_ERROR("invalid ptr[%p][%p]", cb_info, msg);
856                 return;
857         }
858
859         REC_LOG_DEBUG("msg[%s]", msg);
860
861         if (!muse_recorder_msg_get(api, msg)) {
862                 REC_LOG_ERROR("failed to get recorder api");
863                 return;
864         }
865
866         if (api == MUSE_RECORDER_CB_EVENT) {
867                 if (!muse_recorder_msg_get(event, msg) ||
868                         !muse_recorder_msg_get(event_class, msg)) {
869                         REC_LOG_ERROR("failed to get event or event_class[%s]", msg);
870                         return;
871                 }
872         } else {
873                 if (!muse_recorder_msg_get(api_class, msg)) {
874                         REC_LOG_ERROR("failed to get api_class[%s]", msg);
875                         return;
876                 }
877         }
878
879         if (api_class == MUSE_RECORDER_API_CLASS_IMMEDIATE) {
880                 if (api >= MUSE_RECORDER_API_MAX) {
881                         REC_LOG_ERROR("invalid api[%d]", api);
882                         return;
883                 }
884
885                 if (!muse_recorder_msg_get(ret, msg)) {
886                         REC_LOG_ERROR("failed to get recorder ret");
887                         return;
888                 }
889
890                 g_mutex_lock(&cb_info->api_mutex[api]);
891
892                 if (api == MUSE_RECORDER_API_GET_DEVICE_STATE) {
893                         g_atomic_int_set(&cb_info->msg_recv_running, 0);
894                         REC_LOG_INFO("get device state done. close client cb handler");
895                 } else {
896                         switch (api) {
897                         case MUSE_RECORDER_API_CREATE:
898                                 if (ret != RECORDER_ERROR_NONE) {
899                                         g_atomic_int_set(&cb_info->msg_recv_running, 0);
900                                         REC_LOG_ERROR("create error [0x%x]. closing..", ret);
901                                 }
902                                 break;
903                         case MUSE_RECORDER_API_DESTROY:
904                                 if (ret == RECORDER_ERROR_NONE) {
905                                         g_atomic_int_set(&cb_info->msg_recv_running, 0);
906                                         REC_LOG_INFO("destroy done. closing..");
907                                 }
908                                 break;
909                         default:
910                                 __recorder_get_api_operation(api, cb_info, msg);
911                                 break;
912                         }
913                 }
914
915                 if (cb_info->api_waiting[api] > 0) {
916                         cb_info->api_ret[api] = ret;
917                         cb_info->api_activating[api] = TRUE;
918
919                         g_cond_signal(&cb_info->api_cond[api]);
920                 } else {
921                         REC_LOG_ERROR("no waiting for api[%d]", api);
922                 }
923
924                 g_mutex_unlock(&cb_info->api_mutex[api]);
925         } else if (api_class == MUSE_RECORDER_API_CLASS_THREAD_SUB || api == MUSE_RECORDER_CB_EVENT) {
926                 __recorder_add_msg_to_queue(cb_info, api, event, event_class, msg, tfd);
927         } else {
928                 REC_LOG_WARNING("unknown recorder api[%d] and api_class[%d]", api, api_class);
929         }
930
931         return;
932 }
933
934
935 static void *_recorder_msg_handler_func(gpointer data)
936 {
937         int api = 0;
938         int type = 0;
939         recorder_message_s *rec_msg = NULL;
940         recorder_idle_event_s *rec_idle_event = NULL;
941         recorder_msg_handler_info_s *handler_info = (recorder_msg_handler_info_s *)data;
942         recorder_cb_info_s *cb_info = NULL;
943
944         if (!handler_info || !handler_info->cb_info) {
945                 REC_LOG_ERROR("NULL handler[%p]", handler_info);
946                 return NULL;
947         }
948
949         cb_info = (recorder_cb_info_s *)handler_info->cb_info;
950         type = handler_info->type;
951
952         REC_LOG_INFO("t[%d] start", type);
953
954         g_mutex_lock(&handler_info->mutex);
955
956         while (g_atomic_int_get(&handler_info->running)) {
957                 if (g_queue_is_empty(handler_info->queue)) {
958                         REC_LOG_VERBOSE("signal wait...");
959                         g_cond_wait(&handler_info->cond, &handler_info->mutex);
960                         REC_LOG_VERBOSE("signal received");
961
962                         if (g_atomic_int_get(&handler_info->running) == 0) {
963                                 REC_LOG_INFO("stop event thread");
964                                 break;
965                         }
966                 }
967
968                 rec_msg = (recorder_message_s *)g_queue_pop_head(handler_info->queue);
969                 g_mutex_unlock(&handler_info->mutex);
970                 if (rec_msg == NULL) {
971                         REC_LOG_ERROR("NULL message");
972                         g_mutex_lock(&handler_info->mutex);
973                         continue;
974                 }
975
976                 api = rec_msg->api;
977
978                 if (api < MUSE_RECORDER_API_MAX) {
979                         int ret = 0;
980
981                         g_mutex_lock(&cb_info->api_mutex[api]);
982
983                         if (muse_recorder_msg_get(ret, rec_msg->recv_msg)) {
984                                 if (cb_info->api_waiting[api] > 0) {
985                                         cb_info->api_ret[api] = ret;
986                                         cb_info->api_activating[api] = TRUE;
987
988                                         REC_LOG_DEBUG("recorder api[%d] - return[0x%x]", api, ret);
989
990                                         g_cond_signal(&cb_info->api_cond[api]);
991                                 } else {
992                                         REC_LOG_ERROR("no waiting for api [%d]", api);
993                                 }
994                         } else {
995                                 REC_LOG_ERROR("t[%d] failed to get ret for api[%d], msg[%s]", type, api, rec_msg->recv_msg);
996                         }
997
998                         g_mutex_unlock(&cb_info->api_mutex[api]);
999                 } else if (api == MUSE_RECORDER_CB_EVENT) {
1000                         switch (rec_msg->event_class) {
1001                         case MUSE_RECORDER_EVENT_CLASS_THREAD_SUB:
1002                                 _recorder_client_user_callback(cb_info, rec_msg->recv_msg, rec_msg->event, rec_msg->tfd);
1003                                 break;
1004                         case MUSE_RECORDER_EVENT_CLASS_THREAD_MAIN:
1005                                 rec_idle_event = g_new0(recorder_idle_event_s, 1);
1006                                 if (rec_idle_event == NULL) {
1007                                         REC_LOG_ERROR("event alloc failed");
1008                                         break;
1009                                 }
1010
1011                                 rec_idle_event->event = rec_msg->event;
1012                                 rec_idle_event->cb_info = cb_info;
1013
1014                                 strncpy(rec_idle_event->recv_msg, rec_msg->recv_msg, sizeof(rec_idle_event->recv_msg));
1015
1016                                 REC_LOG_DEBUG("add recorder event[%d][%p] to IDLE", rec_msg->event, rec_idle_event);
1017
1018                                 g_mutex_lock(&g_rec_idle_event_lock);
1019                                 cb_info->idle_event_list = g_list_append(cb_info->idle_event_list, (gpointer)rec_idle_event);
1020                                 g_mutex_unlock(&g_rec_idle_event_lock);
1021
1022                                 g_idle_add_full(G_PRIORITY_DEFAULT,
1023                                         (GSourceFunc)_recorder_idle_event_callback,
1024                                         (gpointer)rec_idle_event,
1025                                         NULL);
1026                                 break;
1027                         default:
1028                                 REC_LOG_ERROR("unknown event class[%d]", rec_msg->event_class);
1029                                 break;
1030                         }
1031                 } else {
1032                         REC_LOG_ERROR("unknown api[%d] message", api);
1033                 }
1034
1035                 g_free(rec_msg);
1036                 rec_msg = NULL;
1037
1038                 g_mutex_lock(&handler_info->mutex);
1039         }
1040
1041         /* remove remained event */
1042         while (!g_queue_is_empty(handler_info->queue)) {
1043                 rec_msg = (recorder_message_s *)g_queue_pop_head(handler_info->queue);
1044                 if (rec_msg) {
1045                         REC_LOG_INFO("remove message[%p]", rec_msg);
1046                         free(rec_msg);
1047                         rec_msg = NULL;
1048                 } else {
1049                         REC_LOG_WARNING("NULL message");
1050                 }
1051         }
1052
1053         g_mutex_unlock(&handler_info->mutex);
1054
1055         REC_LOG_INFO("return");
1056
1057         return NULL;
1058 }
1059
1060
1061 static void *_recorder_msg_recv_func(gpointer data)
1062 {
1063         int i = 0;
1064         int recv_length = 0;
1065         int tfd[MUSE_NUM_FD] = {-1, -1, -1, -1};
1066         char *recv_msg = NULL;
1067         recorder_cb_info_s *cb_info = (recorder_cb_info_s *)data;
1068
1069         if (cb_info == NULL) {
1070                 REC_LOG_ERROR("cb_info NULL");
1071                 return NULL;
1072         }
1073
1074         REC_LOG_INFO("start");
1075
1076         recv_msg = cb_info->recv_msg;
1077
1078         while (g_atomic_int_get(&cb_info->msg_recv_running)) {
1079                 for (i = 0 ; i < MUSE_NUM_FD ; i++)
1080                         tfd[i] = -1;
1081
1082                 recv_length = muse_core_msg_recv_fd(cb_info->fd, recv_msg, MUSE_MSG_MAX_LENGTH, tfd);
1083                 if (recv_length <= 0) {
1084 //LCOV_EXCL_START
1085                         cb_info->is_server_connected = FALSE;
1086                         REC_LOG_ERROR("receive msg failed - server disconnected");
1087                         break;
1088 //LCOV_EXCL_STOP
1089                 }
1090
1091                 recv_msg[recv_length] = '\0';
1092
1093                 REC_LOG_DEBUG("recv msg[%s], length[%d]", recv_msg, recv_length);
1094
1095                 __recorder_process_msg(cb_info, recv_msg, tfd);
1096         }
1097
1098         REC_LOG_INFO("client cb exit - server connected[%d]", cb_info->is_server_connected);
1099
1100         if (!cb_info->is_server_connected) {
1101 //LCOV_EXCL_START
1102                 /* send error msg for server disconnection */
1103                 char *error_msg = muse_core_msg_new(MUSE_RECORDER_CB_EVENT,
1104                         MUSE_TYPE_INT, "error", RECORDER_ERROR_SERVICE_DISCONNECTED,
1105                         MUSE_TYPE_INT, "current_state", RECORDER_STATE_NONE,
1106                         NULL);
1107
1108                 if (!error_msg) {
1109                         REC_LOG_ERROR("error_msg failed");
1110                         goto CB_HANDLER_EXIT;
1111                 }
1112
1113                 REC_LOG_ERROR("add error msg for service disconnection done");
1114
1115                 __recorder_add_msg_to_queue(cb_info,
1116                         MUSE_RECORDER_CB_EVENT,
1117                         MUSE_RECORDER_EVENT_TYPE_ERROR,
1118                         MUSE_RECORDER_EVENT_CLASS_THREAD_MAIN,
1119                         error_msg,
1120                         NULL);
1121
1122                 muse_core_msg_free(error_msg);
1123                 error_msg = NULL;
1124
1125                 REC_LOG_ERROR("add error msg for service disconnection done");
1126 //LCOV_EXCL_STOP
1127         }
1128
1129 CB_HANDLER_EXIT:
1130         return NULL;
1131 }
1132
1133
1134 static bool __create_msg_handler_thread(recorder_msg_handler_info_s *handler_info,
1135         int type, const char *thread_name, recorder_cb_info_s *cb_info)
1136 {
1137         if (!handler_info || !thread_name || !cb_info) {
1138                 REC_LOG_ERROR("t[%d] NULL[%p][%p][%p]",
1139                         type, handler_info, thread_name, cb_info);
1140                 return false;
1141         }
1142
1143         REC_LOG_INFO("t[%d]", type);
1144
1145         handler_info->type = type;
1146         handler_info->queue = g_queue_new();
1147         if (handler_info->queue == NULL) {
1148                 REC_LOG_ERROR("t[%d] queue failed", type);
1149                 return false;
1150         }
1151
1152         g_mutex_init(&handler_info->mutex);
1153         g_cond_init(&handler_info->cond);
1154
1155         handler_info->cb_info = (void *)cb_info;
1156         g_atomic_int_set(&handler_info->running, 1);
1157
1158         handler_info->thread = g_thread_try_new(thread_name,
1159                 _recorder_msg_handler_func, (gpointer)handler_info, NULL);
1160         if (handler_info->thread == NULL) {
1161 //LCOV_EXCL_START
1162                 REC_LOG_ERROR("t[%d] thread failed", type);
1163
1164                 g_mutex_clear(&handler_info->mutex);
1165                 g_cond_clear(&handler_info->cond);
1166                 g_queue_free(handler_info->queue);
1167                 handler_info->queue = NULL;
1168
1169                 return false;
1170 //LCOV_EXCL_STOP
1171         }
1172
1173         REC_LOG_INFO("t[%d] done", type);
1174
1175         return true;
1176 }
1177
1178
1179 static void __destroy_msg_handler_thread(recorder_msg_handler_info_s *handler_info)
1180 {
1181         int type = 0;
1182
1183         if (!handler_info) {
1184                 REC_LOG_ERROR("NULL handler");
1185                 return;
1186         }
1187
1188         if (!handler_info->thread) {
1189                 REC_LOG_WARNING("thread is not created");
1190                 return;
1191         }
1192
1193         type = handler_info->type;
1194
1195         REC_LOG_INFO("t[%d] thread[%p]", type, handler_info->thread);
1196
1197         g_mutex_lock(&handler_info->mutex);
1198         g_atomic_int_set(&handler_info->running, 0);
1199         g_cond_signal(&handler_info->cond);
1200         g_mutex_unlock(&handler_info->mutex);
1201
1202         g_thread_join(handler_info->thread);
1203         handler_info->thread = NULL;
1204
1205         g_mutex_clear(&handler_info->mutex);
1206         g_cond_clear(&handler_info->cond);
1207         g_queue_free(handler_info->queue);
1208         handler_info->queue = NULL;
1209
1210         REC_LOG_INFO("t[%d] done", type);
1211
1212         return;
1213 }
1214
1215
1216 static recorder_cb_info_s *_recorder_client_callback_new(gint sockfd)
1217 {
1218         recorder_cb_info_s *cb_info = NULL;
1219         gint i = 0;
1220
1221         g_return_val_if_fail(sockfd > 0, NULL);
1222
1223         cb_info = g_new0(recorder_cb_info_s, 1);
1224         if (cb_info == NULL) {
1225                 REC_LOG_ERROR("cb_info failed");
1226                 goto ErrorExit;
1227         }
1228
1229         cb_info->api_waiting[MUSE_RECORDER_API_CREATE] = 1;
1230
1231         for (i = 0 ; i < MUSE_RECORDER_API_MAX ; i++) {
1232                 g_mutex_init(&cb_info->api_mutex[i]);
1233                 g_cond_init(&cb_info->api_cond[i]);
1234         }
1235
1236         for (i = 0 ; i < MUSE_RECORDER_EVENT_TYPE_NUM ; i++)
1237                 g_mutex_init(&cb_info->user_cb_mutex[i]);
1238
1239         /* message handler thread */
1240         if (!__create_msg_handler_thread(&cb_info->msg_handler_info,
1241                 _RECORDER_MESSAGE_HANDLER_TYPE_GENERAL, "recorder_msg_handler", cb_info)) {
1242                 REC_LOG_ERROR("msg_handler_info failed");
1243                 goto ErrorExit;
1244         }
1245
1246         /* message handler thread for audio stream callback */
1247         if (!__create_msg_handler_thread(&cb_info->audio_stream_cb_info,
1248                 _RECORDER_MESSAGE_HANDLER_TYPE_AUDIO_STREAM_CB, "recorder_msg_handler:audio_stream_cb", cb_info)) {
1249                 REC_LOG_ERROR("audio_stream_cb_info failed");
1250                 goto ErrorExit;
1251         }
1252
1253         /* message handler thread for muxed stream callback */
1254         if (!__create_msg_handler_thread(&cb_info->muxed_stream_cb_info,
1255                 _RECORDER_MESSAGE_HANDLER_TYPE_MUXED_STREAM_CB, "recorder_msg_handler:muxed_stream_cb", cb_info)) {
1256                 REC_LOG_ERROR("muxed_stream_cb_info failed");
1257                 goto ErrorExit;
1258         }
1259
1260         cb_info->fd = sockfd;
1261
1262         /* message receive thread */
1263         g_atomic_int_set(&cb_info->msg_recv_running, 1);
1264         cb_info->msg_recv_thread = g_thread_try_new("recorder_msg_recv",
1265                 _recorder_msg_recv_func, (gpointer)cb_info, NULL);
1266         if (cb_info->msg_recv_thread == NULL) {
1267                 REC_LOG_ERROR("message receive thread creation failed");
1268                 goto ErrorExit;
1269         }
1270
1271         cb_info->is_server_connected = TRUE;
1272
1273         return cb_info;
1274 //LCOV_EXCL_START
1275 ErrorExit:
1276         if (cb_info) {
1277                 __destroy_msg_handler_thread(&cb_info->msg_handler_info);
1278                 __destroy_msg_handler_thread(&cb_info->audio_stream_cb_info);
1279                 __destroy_msg_handler_thread(&cb_info->muxed_stream_cb_info);
1280
1281                 for (i = 0 ; i < MUSE_RECORDER_EVENT_TYPE_NUM ; i++)
1282                         g_mutex_clear(&cb_info->user_cb_mutex[i]);
1283
1284                 for (i = 0 ; i < MUSE_RECORDER_API_MAX ; i++) {
1285                         g_mutex_clear(&cb_info->api_mutex[i]);
1286                         g_cond_clear(&cb_info->api_cond[i]);
1287                 }
1288
1289                 g_free(cb_info);
1290                 cb_info = NULL;
1291         }
1292
1293         return NULL;
1294 //LCOV_EXCL_STOP
1295 }
1296
1297 static int _recorder_client_wait_for_cb_return(muse_recorder_api_e api, recorder_cb_info_s *cb_info, int time_out)
1298 {
1299         int ret = RECORDER_ERROR_NONE;
1300         gint64 end_time;
1301
1302         if (!cb_info->is_server_connected) {
1303                 REC_LOG_ERROR("server is disconnected");
1304                 return RECORDER_ERROR_SERVICE_DISCONNECTED;
1305         }
1306
1307         g_mutex_lock(&(cb_info->api_mutex[api]));
1308
1309         REC_LOG_INFO("api[%d], timeout[%d]sec", api, time_out);
1310
1311         end_time = g_get_monotonic_time() + time_out * G_TIME_SPAN_SECOND;
1312
1313         while (!cb_info->api_activating[api]) {
1314                 if (time_out == RECORDER_CB_NO_TIMEOUT) {
1315                         g_cond_wait(&(cb_info->api_cond[api]), &(cb_info->api_mutex[api]));
1316                         REC_LOG_WARNING("api[%d] returned[0x%x]", api, cb_info->api_ret[api]);
1317                 } else if (!g_cond_wait_until(&(cb_info->api_cond[api]), &(cb_info->api_mutex[api]), end_time)) {
1318                         REC_LOG_ERROR("api[%d] was TIMED OUT!", api);
1319                         ret = RECORDER_ERROR_INVALID_OPERATION;
1320                         goto _CB_RETURN_END;
1321                 }
1322
1323                 if (!cb_info->api_activating[api])
1324                         REC_LOG_WARNING("invalid signal received, wait again...");
1325         }
1326
1327         ret = cb_info->api_ret[api];
1328         cb_info->api_activating[api] = FALSE;
1329
1330 _CB_RETURN_END:
1331         g_mutex_unlock(&(cb_info->api_mutex[api]));
1332
1333         if (ret != RECORDER_ERROR_NONE)
1334                 REC_LOG_ERROR("ERROR : api[%d] - ret[0x%x]", api, ret);
1335
1336         return ret;
1337 }
1338
1339
1340 static int __send_msg_free(muse_recorder_api_e api, recorder_cb_info_s *cb_info,
1341         char *msg, int timeout)
1342 {
1343         int ret = RECORDER_ERROR_NONE;
1344         int send_ret = 0;
1345
1346         if (!cb_info) {
1347                 REC_LOG_ERROR("NULL handle");
1348                 return RECORDER_ERROR_INVALID_PARAMETER;
1349         }
1350
1351         if (!msg) {
1352                 REC_LOG_ERROR("NULL msg");
1353                 return RECORDER_ERROR_OUT_OF_MEMORY;
1354         }
1355
1356         __recorder_update_api_waiting(cb_info, api, 1);
1357
1358         if (cb_info->is_server_connected)
1359                 send_ret = muse_core_msg_send(cb_info->fd, msg);
1360
1361         if (send_ret < 0) {
1362                 REC_LOG_ERROR("message send failed");
1363                 ret = RECORDER_ERROR_INVALID_OPERATION;
1364         } else {
1365                 ret = _recorder_client_wait_for_cb_return(api, cb_info, timeout);
1366         }
1367
1368         __recorder_update_api_waiting(cb_info, api, -1);
1369
1370         muse_core_msg_free(msg);
1371
1372         REC_LOG_INFO("api[%d] - ret[0x%x]", api, ret);
1373
1374         return ret;
1375 }
1376
1377
1378 static int _recorder_msg_send(muse_recorder_api_e api, recorder_cb_info_s *cb_info,
1379         int *ret, int timeout)
1380 {
1381         if (!cb_info || !ret) {
1382                 REC_LOG_ERROR("invalid pointer for api[%d] -[%p][%p]", api, cb_info, ret);
1383                 return RECORDER_ERROR_INVALID_PARAMETER;
1384         }
1385
1386         *ret = __send_msg_free(api, cb_info, muse_core_msg_new(api, NULL), timeout);
1387
1388         return RECORDER_ERROR_NONE;
1389 }
1390
1391
1392 static int _recorder_msg_send_param(muse_recorder_api_e api, recorder_cb_info_s *cb_info,
1393         int *ret, int type, const char *name, void *value)
1394 {
1395         char *msg = NULL;
1396
1397         if (!cb_info || !ret || !name || !value) {
1398                 REC_LOG_ERROR("NULL param for api[%d] -[%p,%p,%p,%p]", api, cb_info, ret, name, value);
1399                 return RECORDER_ERROR_INVALID_PARAMETER;
1400         }
1401
1402         switch (type) {
1403         case MUSE_TYPE_INT:
1404                 msg = muse_core_msg_new(api, type, name, *(int *)value, NULL);
1405                 break;
1406         case MUSE_TYPE_DOUBLE:
1407                 msg = muse_core_msg_new(api, type, name, *(double *)value, NULL);
1408                 break;
1409         case MUSE_TYPE_STRING:
1410                 msg = muse_core_msg_new(api, type, name, (char *)value, NULL);
1411                 break;
1412         default:
1413                 REC_LOG_ERROR("unknown type[%d]", type);
1414                 break;
1415         }
1416
1417         *ret = __send_msg_free(api, cb_info, msg, RECORDER_CB_TIMEOUT);
1418
1419         return RECORDER_ERROR_NONE;
1420 }
1421
1422
1423 static int _recorder_set_int(recorder_h recorder, muse_recorder_api_e api, const char *name, int value)
1424 {
1425         int ret = RECORDER_ERROR_NONE;
1426         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1427
1428         if (!pc || !pc->cb_info) {
1429                 REC_LOG_ERROR("NULL handle");
1430                 return RECORDER_ERROR_INVALID_PARAMETER;
1431         }
1432
1433         REC_LOG_INFO("api[%d] - value[%d]", api, value);
1434
1435         _recorder_msg_send_param(api, pc->cb_info, &ret,
1436                 MUSE_TYPE_INT, name, (void *)&value);
1437
1438         REC_LOG_INFO("api[%d] - ret[0x%x]", api, ret);
1439
1440         return ret;
1441 }
1442
1443
1444 static int _recorder_set_cb(recorder_h recorder, muse_recorder_api_e api, muse_recorder_event_e event, bool is_set, void *callback, void *user_data)
1445 {
1446         int ret = RECORDER_ERROR_NONE;
1447         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1448
1449         if (!pc || !pc->cb_info) {
1450                 REC_LOG_ERROR("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
1451                 return RECORDER_ERROR_INVALID_PARAMETER;
1452         }
1453
1454         REC_LOG_INFO("Enter[%p] - api[%d], is_set[%d], cb[%p], user_data[%p]",
1455                 recorder, api, is_set, callback, user_data);
1456
1457         if (is_set && callback == NULL) {
1458                 REC_LOG_ERROR("NULL callback");
1459                 return RECORDER_ERROR_INVALID_PARAMETER;
1460         }
1461
1462         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1463
1464         if (ret == RECORDER_ERROR_NONE) {
1465                 g_mutex_lock(&pc->cb_info->user_cb_mutex[event]);
1466
1467                 pc->cb_info->user_cb[event] = callback;
1468                 pc->cb_info->user_data[event] = user_data;
1469
1470                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[event]);
1471         }
1472
1473         REC_LOG_INFO("ret[0x%x]", ret);
1474
1475         return ret;
1476 }
1477
1478
1479 static void _recorder_client_callback_destroy(recorder_cb_info_s *cb_info)
1480 {
1481         gint i = 0;
1482
1483         g_return_if_fail(cb_info != NULL);
1484
1485         /* remove idle event */
1486         _recorder_deactivate_idle_event_all(cb_info);
1487
1488         REC_LOG_INFO("MSG receive thread[%p] destroy", cb_info->msg_recv_thread);
1489
1490         g_thread_join(cb_info->msg_recv_thread);
1491         cb_info->msg_recv_thread = NULL;
1492
1493         REC_LOG_INFO("msg_recv thread removed");
1494
1495         __destroy_msg_handler_thread(&cb_info->msg_handler_info);
1496         __destroy_msg_handler_thread(&cb_info->audio_stream_cb_info);
1497         __destroy_msg_handler_thread(&cb_info->muxed_stream_cb_info);
1498
1499         for (i = 0 ; i < MUSE_RECORDER_EVENT_TYPE_NUM ; i++)
1500                 g_mutex_clear(&cb_info->user_cb_mutex[i]);
1501
1502         for (i = 0 ; i < MUSE_RECORDER_API_MAX ; i++) {
1503                 g_mutex_clear(&cb_info->api_mutex[i]);
1504                 g_cond_clear(&cb_info->api_cond[i]);
1505         }
1506
1507         if (cb_info->fd > -1) {
1508                 muse_client_close(cb_info->fd);
1509                 cb_info->fd = -1;
1510         }
1511
1512         if (cb_info->bufmgr) {
1513                 tbm_bufmgr_deinit(cb_info->bufmgr);
1514                 cb_info->bufmgr = NULL;
1515         }
1516         if (cb_info->get_filename) {
1517                 free(cb_info->get_filename);
1518                 cb_info->get_filename = NULL;
1519         }
1520
1521         g_free(cb_info);
1522         cb_info = NULL;
1523
1524         return;
1525 }
1526
1527
1528 static bool _recorder_storage_device_supported_cb(int storage_id, storage_type_e type, storage_state_e state, const char *path, void *user_data)
1529 {
1530         char **root_directory = (char **)user_data;
1531
1532         if (root_directory == NULL) {
1533                 REC_LOG_ERROR("user data is NULL");
1534                 return false;
1535         }
1536
1537         REC_LOG_INFO("storage id[%d], type[%d], state[%d], path[%s]",
1538                 storage_id, type, state, path ? path : "NULL");
1539
1540         if (type == STORAGE_TYPE_INTERNAL && path) {
1541                 if (*root_directory) {
1542                         free(*root_directory);
1543                         *root_directory = NULL;
1544                 }
1545
1546                 *root_directory = strdup(path);
1547                 if (*root_directory) {
1548                         REC_LOG_INFO("get root directory[%s]", *root_directory);
1549                         return false;
1550                 } else {
1551                         REC_LOG_ERROR("strdup[%s] failed", path);
1552                 }
1553         }
1554
1555         return true;
1556 }
1557
1558 static int _recorder_client_get_root_directory(char **root_directory)
1559 {
1560         int ret = STORAGE_ERROR_NONE;
1561
1562         if (root_directory == NULL) {
1563                 REC_LOG_ERROR("user data is NULL");
1564                 return false;
1565         }
1566
1567         ret = storage_foreach_device_supported((storage_device_supported_cb)_recorder_storage_device_supported_cb, root_directory);
1568         if (ret != STORAGE_ERROR_NONE) {
1569                 REC_LOG_ERROR("storage_foreach_device_supported failed[0x%x]", ret);
1570                 return false;
1571         }
1572
1573         return true;
1574 }
1575
1576 static int _recorder_create_common(recorder_h *recorder, muse_recorder_type_e type, camera_h camera)
1577 {
1578         int ret = RECORDER_ERROR_NONE;
1579         int destroy_ret = RECORDER_ERROR_NONE;
1580         int sock_fd = -1;
1581         int module_index = -1;
1582         int log_level = g_recorder_log_level;
1583         int send_ret = 0;
1584         char *send_msg = NULL;
1585         char *root_directory = NULL;
1586         intptr_t camera_handle = 0;
1587         intptr_t handle = 0;
1588         tbm_bufmgr bufmgr = NULL;
1589         recorder_cli_s *pc = NULL;
1590
1591         REC_LOG_INFO("type[%d]", type);
1592
1593         if (recorder == NULL) {
1594                 REC_LOG_ERROR("NULL pointer for recorder handle");
1595                 return RECORDER_ERROR_INVALID_PARAMETER;
1596         }
1597
1598         if (type == MUSE_RECORDER_TYPE_VIDEO && camera == NULL) {
1599                 REC_LOG_ERROR("NULL pointer for camera handle on video recorder mode");
1600                 return RECORDER_ERROR_INVALID_PARAMETER;
1601         }
1602
1603         bufmgr = tbm_bufmgr_init(-1);
1604         if (bufmgr == NULL) {
1605                 REC_LOG_ERROR("get tbm bufmgr failed");
1606                 return RECORDER_ERROR_INVALID_OPERATION;
1607         }
1608
1609         pc = g_new0(recorder_cli_s, 1);
1610         if (pc == NULL) {
1611                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
1612                 goto _ERR_RECORDER_EXIT;
1613         }
1614
1615         sock_fd = muse_client_new();
1616         if (sock_fd < 0) {
1617 //LCOV_EXCL_START
1618                 REC_LOG_ERROR("muse_client_new failed - returned fd[%d]", sock_fd);
1619                 ret = RECORDER_ERROR_INVALID_OPERATION;
1620                 goto _ERR_RECORDER_EXIT;
1621 //LCOV_EXCL_STOP
1622         }
1623
1624         if (muse_client_get_module_index(MODULE_NAME, &module_index) != MM_ERROR_NONE) {
1625                 REC_LOG_ERROR("muse client get module index failed");
1626                 ret = RECORDER_ERROR_INVALID_OPERATION;
1627                 goto _ERR_RECORDER_EXIT;
1628         }
1629
1630         if (type == MUSE_RECORDER_TYPE_AUDIO) {
1631                 send_msg = muse_core_msg_new(MUSE_RECORDER_API_CREATE,
1632                         MUSE_TYPE_INT, "module", module_index,
1633                         MUSE_TYPE_INT, PARAM_RECORDER_TYPE, MUSE_RECORDER_TYPE_AUDIO,
1634                         MUSE_TYPE_INT, "pid", getpid(),
1635                         NULL);
1636         } else {
1637                 pc->camera = camera;
1638                 camera_handle = (intptr_t)((camera_cli_s *)camera)->remote_handle;
1639                 send_msg = muse_core_msg_new(MUSE_RECORDER_API_CREATE,
1640                         MUSE_TYPE_INT, "module", module_index,
1641                         MUSE_TYPE_INT, PARAM_RECORDER_TYPE, MUSE_RECORDER_TYPE_VIDEO,
1642                         MUSE_TYPE_INT, "pid", getpid(),
1643                         MUSE_TYPE_POINTER, "camera_handle", camera_handle,
1644                         NULL);
1645         }
1646
1647         if (!send_msg) {
1648 //LCOV_EXCL_START
1649                 REC_LOG_ERROR("NULL msg");
1650                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
1651                 goto _ERR_RECORDER_EXIT;
1652 //LCOV_EXCL_STOP
1653         }
1654
1655         REC_LOG_INFO("sock_fd[%d], msg[%s]", sock_fd, send_msg);
1656
1657         send_ret = muse_core_msg_send(sock_fd, send_msg);
1658
1659         muse_core_msg_free(send_msg);
1660         send_msg = NULL;
1661
1662         if (send_ret < 0) {
1663 //LCOV_EXCL_START
1664                 REC_LOG_ERROR("send msg failed[%d]", errno);
1665                 ret = RECORDER_ERROR_INVALID_OPERATION;
1666                 goto _ERR_RECORDER_EXIT;
1667 //LCOV_EXCL_STOP
1668         }
1669
1670         pc->cb_info = _recorder_client_callback_new(sock_fd);
1671         if (pc->cb_info == NULL) {
1672                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
1673                 goto _ERR_RECORDER_EXIT;
1674         }
1675
1676         sock_fd = -1;
1677
1678         ret = _recorder_client_wait_for_cb_return(MUSE_RECORDER_API_CREATE, pc->cb_info, RECORDER_CB_TIMEOUT);
1679
1680         pc->cb_info->api_waiting[MUSE_RECORDER_API_CREATE] = 0;
1681
1682         if (ret != RECORDER_ERROR_NONE) {
1683                 REC_LOG_ERROR("API_CREATE failed[0x%x]", ret);
1684                 goto _ERR_RECORDER_EXIT;
1685         }
1686
1687         /* get log level from message */
1688         muse_recorder_msg_get(log_level, pc->cb_info->recv_msg);
1689         g_recorder_log_level = log_level;
1690
1691         muse_recorder_msg_get_pointer(handle, pc->cb_info->recv_msg);
1692         if (handle == 0) {
1693 //LCOV_EXCL_START
1694                 REC_LOG_ERROR("Receiving Handle Failed!!");
1695                 ret = RECORDER_ERROR_INVALID_OPERATION;
1696                 goto _ERR_RECORDER_AFTER_CREATE;
1697 //LCOV_EXCL_STOP
1698         }
1699
1700         if (!_recorder_client_get_root_directory(&root_directory) || root_directory == NULL) {
1701 //LCOV_EXCL_START
1702                 REC_LOG_ERROR("failed to get root directory of internal storage");
1703                 ret = RECORDER_ERROR_INVALID_OPERATION;
1704                 goto _ERR_RECORDER_AFTER_CREATE;
1705 //LCOV_EXCL_STOP
1706         }
1707
1708         REC_LOG_INFO("root directory[%s], log level[%d]", root_directory, g_recorder_log_level);
1709
1710         _recorder_msg_send_param(MUSE_RECORDER_API_ATTR_SET_ROOT_DIRECTORY, pc->cb_info, &ret,
1711                 MUSE_TYPE_STRING, "root_directory", (void *)root_directory);
1712
1713         if (ret != RECORDER_ERROR_NONE) {
1714                 REC_LOG_ERROR("failed to set root directory[%s]", root_directory);
1715                 ret = RECORDER_ERROR_INVALID_OPERATION;
1716                 goto _ERR_RECORDER_AFTER_CREATE;
1717         }
1718
1719         free(root_directory);
1720         root_directory = NULL;
1721
1722         pc->remote_handle = handle;
1723         pc->cb_info->bufmgr = bufmgr;
1724
1725         REC_LOG_INFO("recorder type[%d][%p] create success : remote handle[%td]",
1726                 type, pc, pc->remote_handle);
1727
1728         *recorder = (recorder_h)pc;
1729
1730         REC_LOG_INFO("done");
1731
1732         return RECORDER_ERROR_NONE;
1733 //LCOV_EXCL_START
1734 _ERR_RECORDER_AFTER_CREATE:
1735         _recorder_msg_send(MUSE_RECORDER_API_DESTROY, pc->cb_info, &destroy_ret, RECORDER_CB_TIMEOUT);
1736         REC_LOG_ERROR("destroy return[0x%x]", destroy_ret);
1737
1738 _ERR_RECORDER_EXIT:
1739         tbm_bufmgr_deinit(bufmgr);
1740         bufmgr = NULL;
1741
1742         if (root_directory) {
1743                 free(root_directory);
1744                 root_directory = NULL;
1745         }
1746
1747         if (sock_fd > -1) {
1748                 muse_client_close(sock_fd);
1749                 sock_fd = -1;
1750         }
1751
1752         if (pc) {
1753                 if (pc->cb_info) {
1754                         _recorder_client_callback_destroy(pc->cb_info);
1755                         pc->cb_info = NULL;
1756                 }
1757                 g_free(pc);
1758                 pc = NULL;
1759         }
1760
1761         return ret;
1762 //LCOV_EXCL_STOP
1763 }
1764
1765
1766 static int _recorder_stop(recorder_h recorder, muse_recorder_api_e api)
1767 {
1768         int ret = RECORDER_ERROR_NONE;
1769         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1770         recorder_state_e current_state = RECORDER_STATE_NONE;
1771
1772         if (!pc || !pc->cb_info) {
1773                 REC_LOG_ERROR("NULL handle");
1774                 return RECORDER_ERROR_INVALID_PARAMETER;
1775         }
1776
1777         REC_LOG_INFO("ENTER - api[%d]", api);
1778
1779         if (pc->camera) {
1780 //LCOV_EXCL_START
1781                 ret = recorder_get_state(recorder, &current_state);
1782                 if (ret != RECORDER_ERROR_NONE) {
1783                         REC_LOG_ERROR("failed to get current state[0x%x]", ret);
1784                         return RECORDER_ERROR_INVALID_OPERATION;
1785                 }
1786
1787                 if (current_state >= RECORDER_STATE_RECORDING) {
1788                         ret = camera_stop_evas_rendering(pc->camera, true);
1789                         if (ret != CAMERA_ERROR_NONE) {
1790                                 REC_LOG_ERROR("camera_stop_evas_rendering failed[0x%x]", ret);
1791                                 return RECORDER_ERROR_INVALID_OPERATION;
1792                         }
1793                 }
1794 //LCOV_EXCL_STOP
1795         }
1796
1797         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1798
1799         if (pc->camera && current_state >= RECORDER_STATE_RECORDING)
1800                 camera_start_evas_rendering(pc->camera);
1801
1802         REC_LOG_INFO("ret[0x%x]", ret);
1803
1804         return ret;
1805 }
1806
1807
1808 int recorder_create_videorecorder(camera_h camera, recorder_h *recorder)
1809 {
1810         return _recorder_create_common(recorder, MUSE_RECORDER_TYPE_VIDEO, camera);
1811 }
1812
1813
1814 int recorder_create_audiorecorder(recorder_h *recorder)
1815 {
1816         return _recorder_create_common(recorder, MUSE_RECORDER_TYPE_AUDIO, NULL);
1817 }
1818
1819
1820 int recorder_get_state(recorder_h recorder, recorder_state_e *state)
1821 {
1822         int ret = RECORDER_ERROR_NONE;
1823         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1824         muse_recorder_api_e api = MUSE_RECORDER_API_GET_STATE;
1825
1826         if (!pc || !pc->cb_info) {
1827                 REC_LOG_ERROR("NULL handle");
1828                 return RECORDER_ERROR_INVALID_PARAMETER;
1829         }
1830
1831         if (state == NULL) {
1832                 REC_LOG_ERROR("NULL pointer state");
1833                 return RECORDER_ERROR_INVALID_PARAMETER;
1834         }
1835
1836         REC_LOG_INFO("Enter, remote_handle[%td]", pc->remote_handle);
1837
1838         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1839
1840         if (ret == RECORDER_ERROR_NONE)
1841                 *state = (recorder_state_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_STATE];
1842
1843         REC_LOG_INFO("ret[0x%x], state[%d]", ret, *state);
1844
1845         return ret;
1846 }
1847
1848
1849 int recorder_destroy(recorder_h recorder)
1850 {
1851         int ret = RECORDER_ERROR_NONE;
1852         muse_recorder_api_e api = MUSE_RECORDER_API_DESTROY;
1853         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1854
1855         if (!pc || !pc->cb_info) {
1856                 REC_LOG_ERROR("NULL handle");
1857                 return RECORDER_ERROR_INVALID_PARAMETER;
1858         }
1859
1860         REC_LOG_INFO("ENTER");
1861
1862         if (pc->cb_info->is_server_connected)
1863                 _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1864         else
1865                 REC_LOG_WARNING("server disconnected. release resource without send message.");
1866
1867         if (ret == RECORDER_ERROR_NONE) {
1868                 _recorder_client_callback_destroy(pc->cb_info);
1869                 g_free(pc);
1870                 pc = NULL;
1871         }
1872
1873         REC_LOG_INFO("ret[0x%x]", ret);
1874
1875         return ret;
1876 }
1877
1878
1879 int recorder_prepare(recorder_h recorder)
1880 {
1881         int ret = RECORDER_ERROR_NONE;
1882         muse_recorder_api_e api = MUSE_RECORDER_API_PREPARE;
1883         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1884
1885         if (!pc || !pc->cb_info) {
1886                 REC_LOG_ERROR("NULL handle");
1887                 return RECORDER_ERROR_INVALID_PARAMETER;
1888         }
1889
1890         REC_LOG_INFO("ENTER");
1891
1892         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1893
1894         REC_LOG_INFO("ret[0x%x]", ret);
1895
1896         if (ret == RECORDER_ERROR_NONE && pc->camera)
1897                 camera_start_evas_rendering(pc->camera);
1898
1899         return ret;
1900 }
1901
1902
1903 int recorder_unprepare(recorder_h recorder)
1904 {
1905         int ret = RECORDER_ERROR_NONE;
1906         muse_recorder_api_e api = MUSE_RECORDER_API_UNPREPARE;
1907         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1908         camera_state_e camera_state = CAMERA_STATE_NONE;
1909
1910         if (!pc || !pc->cb_info) {
1911                 REC_LOG_ERROR("NULL handle");
1912                 return RECORDER_ERROR_INVALID_PARAMETER;
1913         }
1914
1915         REC_LOG_INFO("ENTER");
1916
1917         if (pc->camera) {
1918 //LCOV_EXCL_START
1919                 ret = camera_get_state(pc->camera, &camera_state);
1920                 if (ret != CAMERA_ERROR_NONE) {
1921                         REC_LOG_ERROR("failed to get camera state[0x%x]", ret);
1922                         return RECORDER_ERROR_INVALID_OPERATION;
1923                 }
1924
1925                 if (camera_state == CAMERA_STATE_PREVIEW) {
1926                         ret = camera_stop_evas_rendering(pc->camera, false);
1927                         if (ret != CAMERA_ERROR_NONE) {
1928                                 REC_LOG_ERROR("camera_stop_evas_rendering failed[0x%x]", ret);
1929                                 return RECORDER_ERROR_INVALID_OPERATION;
1930                         }
1931                 }
1932 //LCOV_EXCL_STOP
1933         }
1934
1935         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1936
1937         REC_LOG_INFO("ret[0x%x]", ret);
1938
1939         return ret;
1940 }
1941
1942
1943 int recorder_start(recorder_h recorder)
1944 {
1945         int ret = RECORDER_ERROR_NONE;
1946         muse_recorder_api_e api = MUSE_RECORDER_API_START;
1947         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1948         recorder_state_e current_state = RECORDER_STATE_NONE;
1949
1950         if (!pc || !pc->cb_info) {
1951                 REC_LOG_ERROR("NULL handle");
1952                 return RECORDER_ERROR_INVALID_PARAMETER;
1953         }
1954
1955         REC_LOG_INFO("ENTER");
1956
1957         if (pc->camera) {
1958 //LCOV_EXCL_START
1959                 ret = recorder_get_state(recorder, &current_state);
1960                 if (ret != RECORDER_ERROR_NONE) {
1961                         REC_LOG_ERROR("failed to get current state[0x%x]", ret);
1962                         return RECORDER_ERROR_INVALID_OPERATION;
1963                 }
1964
1965                 if (current_state == RECORDER_STATE_READY) {
1966                         ret = camera_stop_evas_rendering(pc->camera, true);
1967                         if (ret != CAMERA_ERROR_NONE) {
1968                                 REC_LOG_ERROR("camera_stop_evas_rendering failed[0x%x]", ret);
1969                                 return RECORDER_ERROR_INVALID_OPERATION;
1970                         }
1971                 }
1972 //LCOV_EXCL_STOP
1973         }
1974
1975         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_NO_TIMEOUT);
1976
1977         if (pc->camera && current_state == RECORDER_STATE_READY)
1978                 camera_start_evas_rendering(pc->camera);
1979
1980         REC_LOG_INFO("ret[0x%x]", ret);
1981
1982         return ret;
1983 }
1984
1985
1986 int recorder_pause(recorder_h recorder)
1987 {
1988         int ret = RECORDER_ERROR_NONE;
1989         muse_recorder_api_e api = MUSE_RECORDER_API_PAUSE;
1990         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1991
1992         if (!pc || !pc->cb_info) {
1993                 REC_LOG_ERROR("NULL handle");
1994                 return RECORDER_ERROR_INVALID_PARAMETER;
1995         }
1996
1997         REC_LOG_INFO("ENTER");
1998
1999         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2000
2001         REC_LOG_INFO("ret[0x%x]", ret);
2002
2003         return ret;
2004 }
2005
2006
2007 int recorder_commit(recorder_h recorder)
2008 {
2009         return _recorder_stop(recorder, MUSE_RECORDER_API_COMMIT);
2010 }
2011
2012
2013 int recorder_cancel(recorder_h recorder)
2014 {
2015         return _recorder_stop(recorder, MUSE_RECORDER_API_CANCEL);
2016 }
2017
2018
2019 int recorder_set_video_resolution(recorder_h recorder, int width, int height)
2020 {
2021         char *msg = NULL;
2022         muse_recorder_api_e api = MUSE_RECORDER_API_SET_VIDEO_RESOLUTION;
2023         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2024
2025         if (!pc || !pc->cb_info) {
2026                 REC_LOG_ERROR("NULL handle");
2027                 return RECORDER_ERROR_INVALID_PARAMETER;
2028         }
2029
2030         REC_LOG_INFO("ENTER");
2031
2032         msg = muse_core_msg_new(api,
2033                 MUSE_TYPE_INT, "width", width,
2034                 MUSE_TYPE_INT, "height", height,
2035                 NULL);
2036
2037         return __send_msg_free(api, pc->cb_info, msg, RECORDER_CB_TIMEOUT);
2038 }
2039
2040
2041 int recorder_get_video_resolution(recorder_h recorder, int *width, int *height)
2042 {
2043         int ret = RECORDER_ERROR_NONE;
2044         muse_recorder_api_e api = MUSE_RECORDER_API_GET_VIDEO_RESOLUTION;
2045         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2046
2047         if (!pc || !pc->cb_info) {
2048                 REC_LOG_ERROR("NULL handle");
2049                 return RECORDER_ERROR_INVALID_PARAMETER;
2050         }
2051
2052         if (!width || !height) {
2053                 REC_LOG_ERROR("NULL pointer width = [%p], height = [%p]", width, height);
2054                 return RECORDER_ERROR_INVALID_PARAMETER;
2055         }
2056
2057         REC_LOG_INFO("ENTER");
2058
2059         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2060
2061         if (ret == RECORDER_ERROR_NONE) {
2062                 *width = pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_RESOLUTION] >> 16;
2063                 *height = (0x0000ffff & pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_RESOLUTION]);
2064         }
2065
2066         REC_LOG_INFO("ret[0x%x],[%d]x%d", ret, *width, *height);
2067
2068         return ret;
2069 }
2070
2071
2072 int recorder_foreach_supported_video_resolution(recorder_h recorder,
2073         recorder_supported_video_resolution_cb foreach_cb, void *user_data)
2074 {
2075         int ret = RECORDER_ERROR_NONE;
2076         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2077         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_VIDEO_RESOLUTION;
2078
2079         if (!pc || !pc->cb_info || foreach_cb == NULL) {
2080                 REC_LOG_ERROR("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2081                 return RECORDER_ERROR_INVALID_PARAMETER;
2082         }
2083
2084         REC_LOG_INFO("Enter, handle[%td]", pc->remote_handle);
2085
2086         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_RESOLUTION] = foreach_cb;
2087         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_RESOLUTION] = user_data;
2088
2089         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2090
2091         REC_LOG_INFO("ret[0x%x]", ret);
2092
2093         return ret;
2094 }
2095
2096
2097 int recorder_get_audio_level(recorder_h recorder, double *level)
2098 {
2099         int ret = RECORDER_ERROR_NONE;
2100         muse_recorder_api_e api = MUSE_RECORDER_API_GET_AUDIO_LEVEL;
2101         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2102
2103         if (!pc || !pc->cb_info || level == NULL) {
2104                 REC_LOG_ERROR("NULL pointer[%p][%p]", pc, level);
2105                 return RECORDER_ERROR_INVALID_PARAMETER;
2106         }
2107
2108         REC_LOG_INFO("ENTER");
2109
2110         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2111
2112         if (ret == RECORDER_ERROR_NONE)
2113                 *level = pc->cb_info->get_double_value[_RECORDER_GET_DOUBLE_AUDIO_LEVEL];
2114
2115         REC_LOG_INFO("ret[0x%x], level %lf", ret, *level);
2116
2117         return ret;
2118 }
2119
2120
2121 int recorder_set_filename(recorder_h recorder, const char *filename)
2122 {
2123         int ret = RECORDER_ERROR_NONE;
2124         size_t length = 0;
2125         muse_recorder_api_e api = MUSE_RECORDER_API_SET_FILENAME;
2126         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2127         char set_filename[RECORDER_FILENAME_MAX] = {'\0',};
2128
2129         if (!pc || !pc->cb_info) {
2130                 REC_LOG_ERROR("NULL handle");
2131                 return RECORDER_ERROR_INVALID_PARAMETER;
2132         }
2133
2134         if (filename == NULL) {
2135                 REC_LOG_ERROR("filename is NULL");
2136                 return RECORDER_ERROR_INVALID_PARAMETER;
2137         }
2138
2139         REC_LOG_INFO("ENTER[%s]", filename);
2140
2141         length = strlen(filename);
2142
2143         if (length >= RECORDER_FILENAME_MAX - 1) {
2144                 REC_LOG_ERROR("too long file name [%zu]", length);
2145                 return RECORDER_ERROR_INVALID_PARAMETER;
2146         }
2147
2148         if (storage_get_origin_internal_path(filename, RECORDER_FILENAME_MAX, set_filename) < 0) {
2149                 /* Cannot convert. Use original path. */
2150                 strncpy(set_filename, filename, length + 1);
2151                 pc->cb_info->is_filename_converted = FALSE;
2152         } else {
2153                 /* Converted. Use converted path. */
2154                 REC_LOG_INFO("Converted filename[%s] ->[%s]", filename, set_filename);
2155                 pc->cb_info->is_filename_converted = TRUE;
2156         }
2157
2158         _recorder_msg_send_param(api, pc->cb_info, &ret,
2159                 MUSE_TYPE_STRING, "set_filename", (void *)set_filename);
2160
2161         REC_LOG_INFO("ret[0x%x]", ret);
2162
2163         return ret;
2164 }
2165
2166
2167 int recorder_get_filename(recorder_h recorder,  char **filename)
2168 {
2169         int ret = RECORDER_ERROR_NONE;
2170         muse_recorder_api_e api = MUSE_RECORDER_API_GET_FILENAME;
2171         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2172         char compat_filename[RECORDER_FILENAME_MAX] = {0, };
2173
2174         if (!pc || !pc->cb_info) {
2175                 REC_LOG_ERROR("NULL handle");
2176                 return RECORDER_ERROR_INVALID_PARAMETER;
2177         }
2178
2179         if (filename == NULL) {
2180                 REC_LOG_ERROR("filename is NULL");
2181                 return RECORDER_ERROR_INVALID_PARAMETER;
2182         }
2183
2184         REC_LOG_INFO("ENTER");
2185
2186         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2187
2188         if (ret == RECORDER_ERROR_NONE) {
2189                 if (pc->cb_info->is_filename_converted == FALSE ||
2190                         storage_get_compat_internal_path(pc->cb_info->get_filename, RECORDER_FILENAME_MAX, compat_filename) < 0) {
2191                         /* Use original path. */
2192                         *filename = pc->cb_info->get_filename;
2193                 } else {
2194                         /* Converted. Use converted path. */
2195                         REC_LOG_INFO("Converted filename[%s] ->[%s]", pc->cb_info->get_filename, compat_filename);
2196                         *filename = strdup(compat_filename);
2197                         free(pc->cb_info->get_filename);
2198                 }
2199
2200                 pc->cb_info->get_filename = NULL;
2201         }
2202
2203         REC_LOG_INFO("ret[0x%x], filename[%s]", ret, (*filename) ? *filename : "NULL");
2204
2205         return ret;
2206 }
2207
2208
2209 int recorder_set_file_format(recorder_h recorder, recorder_file_format_e format)
2210 {
2211         return _recorder_set_int(recorder, MUSE_RECORDER_API_SET_FILE_FORMAT, "set_format", format);
2212 }
2213
2214
2215 int recorder_get_file_format(recorder_h recorder, recorder_file_format_e *format)
2216 {
2217         int ret = RECORDER_ERROR_NONE;
2218         muse_recorder_api_e api = MUSE_RECORDER_API_GET_FILE_FORMAT;
2219         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2220
2221         if (!pc || !pc->cb_info) {
2222                 REC_LOG_ERROR("NULL handle");
2223                 return RECORDER_ERROR_INVALID_PARAMETER;
2224         }
2225
2226         if (format == NULL) {
2227                 REC_LOG_ERROR("NULL pointer data");
2228                 return RECORDER_ERROR_INVALID_PARAMETER;
2229         }
2230
2231         REC_LOG_INFO("ENTER");
2232
2233         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2234
2235         if (ret == RECORDER_ERROR_NONE)
2236                 *format = (recorder_file_format_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_FILE_FORMAT];
2237
2238         REC_LOG_INFO("ret[0x%x], format[%d]", ret, *format);
2239
2240         return ret;
2241 }
2242
2243
2244 int recorder_set_sound_stream_info(recorder_h recorder, sound_stream_info_h stream_info)
2245 {
2246         int ret = RECORDER_ERROR_NONE;
2247         muse_recorder_api_e api = MUSE_RECORDER_API_SET_SOUND_STREAM_INFO;
2248         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2249         bool is_available = false;
2250         int stream_index = 0;
2251         char *stream_type = NULL;
2252         char *msg = NULL;
2253
2254         if (!pc || !pc->cb_info || stream_info == NULL) {
2255                 REC_LOG_ERROR("NULL handle");
2256                 return RECORDER_ERROR_INVALID_PARAMETER;
2257         }
2258
2259         REC_LOG_INFO("ENTER");
2260
2261         ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_RECORDER, &is_available);
2262         if (ret != SOUND_MANAGER_ERROR_NONE) {
2263                 REC_LOG_ERROR("stream info verification failed");
2264                 return RECORDER_ERROR_INVALID_OPERATION;
2265         }
2266
2267         if (is_available == false) {
2268                 REC_LOG_ERROR("stream information is not available");
2269                 return RECORDER_ERROR_INVALID_OPERATION;
2270         }
2271
2272         ret = sound_manager_get_type_from_stream_information(stream_info, &stream_type);
2273         ret |= sound_manager_get_index_from_stream_information(stream_info, &stream_index);
2274
2275         if (ret != SOUND_MANAGER_ERROR_NONE) {
2276                 REC_LOG_ERROR("sound manager failed[0x%x]", ret);
2277                 return RECORDER_ERROR_INVALID_OPERATION;
2278         }
2279
2280         msg = muse_core_msg_new(api,
2281                 MUSE_TYPE_STRING, "stream_type", stream_type,
2282                 MUSE_TYPE_INT, "stream_index", stream_index,
2283                 NULL);
2284
2285         return __send_msg_free(api, pc->cb_info, msg, RECORDER_CB_TIMEOUT);
2286 }
2287
2288
2289 int recorder_set_state_changed_cb(recorder_h recorder, recorder_state_changed_cb callback, void *user_data)
2290 {
2291         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_STATE_CHANGED_CB,
2292                 MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE, true, callback, user_data);
2293 }
2294
2295
2296 int recorder_unset_state_changed_cb(recorder_h recorder)
2297 {
2298         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_STATE_CHANGED_CB,
2299                 MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE, false, NULL, NULL);
2300 }
2301
2302
2303 int recorder_set_interrupted_cb(recorder_h recorder, recorder_interrupted_cb callback, void *user_data)
2304 {
2305         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_INTERRUPTED_CB,
2306                 MUSE_RECORDER_EVENT_TYPE_INTERRUPTED, true, callback, user_data);
2307 }
2308
2309
2310 int recorder_unset_interrupted_cb(recorder_h recorder)
2311 {
2312         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_INTERRUPTED_CB,
2313                 MUSE_RECORDER_EVENT_TYPE_INTERRUPTED, false, NULL, NULL);
2314 }
2315
2316
2317 int recorder_set_interrupt_started_cb(recorder_h recorder, recorder_interrupt_started_cb callback, void *user_data)
2318 {
2319         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_INTERRUPT_STARTED_CB,
2320                 MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED, true, callback, user_data);
2321 }
2322
2323
2324 int recorder_unset_interrupt_started_cb(recorder_h recorder)
2325 {
2326         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_INTERRUPT_STARTED_CB,
2327                 MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED, false, NULL, NULL);
2328 }
2329
2330
2331 int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb callback, void *user_data)
2332 {
2333         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_AUDIO_STREAM_CB,
2334                 MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM, true, callback, user_data);
2335 }
2336
2337
2338 int recorder_unset_audio_stream_cb(recorder_h recorder)
2339 {
2340         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_AUDIO_STREAM_CB,
2341                 MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM, false, NULL, NULL);
2342 }
2343
2344
2345 int recorder_set_muxed_stream_cb(recorder_h recorder, recorder_muxed_stream_cb callback, void *user_data)
2346 {
2347         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_MUXED_STREAM_CB,
2348                 MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM, true, callback, user_data);
2349 }
2350
2351
2352 int recorder_unset_muxed_stream_cb(recorder_h recorder)
2353 {
2354         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_MUXED_STREAM_CB,
2355                 MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM, false, NULL, NULL);
2356 }
2357
2358
2359 int recorder_set_video_encode_decision_cb(recorder_h recorder, recorder_video_encode_decision_cb callback, void *user_data)
2360 {
2361         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_VIDEO_ENCODE_DECISION_CB,
2362                 MUSE_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION, true, callback, user_data);
2363 }
2364
2365
2366 int recorder_unset_video_encode_decision_cb(recorder_h recorder)
2367 {
2368         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_VIDEO_ENCODE_DECISION_CB,
2369                 MUSE_RECORDER_EVENT_TYPE_VIDEO_ENCODE_DECISION, false, NULL, NULL);
2370 }
2371
2372
2373 int recorder_set_error_cb(recorder_h recorder, recorder_error_cb callback, void *user_data)
2374 {
2375         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_ERROR_CB,
2376                 MUSE_RECORDER_EVENT_TYPE_ERROR, true, callback, user_data);
2377 }
2378
2379
2380 int recorder_unset_error_cb(recorder_h recorder)
2381 {
2382         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_ERROR_CB,
2383                 MUSE_RECORDER_EVENT_TYPE_ERROR, false, NULL, NULL);
2384 }
2385
2386
2387 int recorder_set_recording_status_cb(recorder_h recorder, recorder_recording_status_cb callback, void *user_data)
2388 {
2389         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_RECORDING_STATUS_CB,
2390                 MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS, true, callback, user_data);
2391 }
2392
2393
2394 int recorder_unset_recording_status_cb(recorder_h recorder)
2395 {
2396         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_RECORDING_STATUS_CB,
2397                 MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS, false, NULL, NULL);
2398 }
2399
2400
2401 int recorder_set_recording_limit_reached_cb(recorder_h recorder, recorder_recording_limit_reached_cb callback, void *user_data)
2402 {
2403         return _recorder_set_cb(recorder, MUSE_RECORDER_API_SET_RECORDING_LIMIT_REACHED_CB,
2404                 MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED, true, callback, user_data);
2405 }
2406
2407
2408 int recorder_unset_recording_limit_reached_cb(recorder_h recorder)
2409 {
2410         return _recorder_set_cb(recorder, MUSE_RECORDER_API_UNSET_RECORDING_LIMIT_REACHED_CB,
2411                 MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED, false, NULL, NULL);
2412 }
2413
2414
2415 int recorder_foreach_supported_file_format(recorder_h recorder, recorder_supported_file_format_cb foreach_cb, void *user_data)
2416 {
2417         int ret = RECORDER_ERROR_NONE;
2418         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2419         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_FILE_FORMAT;
2420
2421         if (!pc || !pc->cb_info || foreach_cb == NULL) {
2422                 REC_LOG_ERROR("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2423                 return RECORDER_ERROR_INVALID_PARAMETER;
2424         }
2425
2426         REC_LOG_INFO("Enter, handle[%td]", pc->remote_handle);
2427
2428         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_FILE_FORMAT] = foreach_cb;
2429         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_FILE_FORMAT] = user_data;
2430
2431         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2432
2433         REC_LOG_INFO("ret[0x%x]", ret);
2434
2435         return ret;
2436 }
2437
2438
2439 int recorder_attr_set_size_limit(recorder_h recorder, int kbyte)
2440 {
2441         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_SIZE_LIMIT, "kbyte", kbyte);
2442 }
2443
2444
2445 int recorder_attr_set_time_limit(recorder_h recorder, int second)
2446 {
2447         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_TIME_LIMIT, "second", second);
2448 }
2449
2450
2451 int recorder_attr_set_audio_device(recorder_h recorder, recorder_audio_device_e device)
2452 {
2453         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_AUDIO_DEVICE, "set_device", device);
2454 }
2455
2456
2457 int recorder_set_audio_encoder(recorder_h recorder, recorder_audio_codec_e codec)
2458 {
2459         return _recorder_set_int(recorder, MUSE_RECORDER_API_SET_AUDIO_ENCODER, "set_codec", codec);
2460 }
2461
2462
2463 int recorder_get_audio_encoder(recorder_h recorder, recorder_audio_codec_e *codec)
2464 {
2465         int ret = RECORDER_ERROR_NONE;
2466         muse_recorder_api_e api = MUSE_RECORDER_API_GET_AUDIO_ENCODER;
2467         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2468
2469         if (!pc || !pc->cb_info) {
2470                 REC_LOG_ERROR("NULL handle");
2471                 return RECORDER_ERROR_INVALID_PARAMETER;
2472         }
2473
2474         if (codec == NULL) {
2475                 REC_LOG_ERROR("codec is NULL");
2476                 return RECORDER_ERROR_INVALID_PARAMETER;
2477         }
2478
2479         REC_LOG_INFO("ENTER");
2480
2481         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2482
2483         if (ret == RECORDER_ERROR_NONE)
2484                 *codec = (recorder_audio_codec_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_ENCODER];
2485
2486         REC_LOG_INFO("ret[0x%x], codec[%d]", ret, *codec);
2487
2488         return ret;
2489 }
2490
2491
2492 int recorder_set_video_encoder(recorder_h recorder, recorder_video_codec_e codec)
2493 {
2494         return _recorder_set_int(recorder, MUSE_RECORDER_API_SET_VIDEO_ENCODER, "set_codec", codec);
2495 }
2496
2497
2498 int recorder_get_video_encoder(recorder_h recorder, recorder_video_codec_e *codec)
2499 {
2500         int ret = RECORDER_ERROR_NONE;
2501         muse_recorder_api_e api = MUSE_RECORDER_API_GET_VIDEO_ENCODER;
2502         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2503
2504         if (!pc || !pc->cb_info) {
2505                 REC_LOG_ERROR("NULL handle");
2506                 return RECORDER_ERROR_INVALID_PARAMETER;
2507         }
2508
2509         if (codec == NULL) {
2510                 REC_LOG_ERROR("codec is NULL");
2511                 return RECORDER_ERROR_INVALID_PARAMETER;
2512         }
2513
2514         REC_LOG_INFO("ENTER");
2515
2516         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2517
2518         if (ret == RECORDER_ERROR_NONE)
2519                 *codec = (recorder_video_codec_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_ENCODER];
2520
2521         REC_LOG_INFO("ret[0x%x], codec[%d]", ret, *codec);
2522
2523         return ret;
2524 }
2525
2526
2527 int recorder_attr_set_audio_samplerate(recorder_h recorder, int samplerate)
2528 {
2529         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_AUDIO_SAMPLERATE, "samplerate", samplerate);
2530 }
2531
2532
2533 int recorder_attr_set_audio_encoder_bitrate(recorder_h recorder, int bitrate)
2534 {
2535         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_AUDIO_ENCODER_BITRATE, "bitrate", bitrate);
2536 }
2537
2538
2539 int recorder_attr_set_video_encoder_bitrate(recorder_h recorder, int bitrate)
2540 {
2541         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_VIDEO_ENCODER_BITRATE, "bitrate", bitrate);
2542 }
2543
2544
2545 int recorder_attr_get_size_limit(recorder_h recorder, int *kbyte)
2546 {
2547         int ret = RECORDER_ERROR_NONE;
2548         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_SIZE_LIMIT;
2549         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2550
2551         if (!pc || !pc->cb_info) {
2552                 REC_LOG_ERROR("NULL handle");
2553                 return RECORDER_ERROR_INVALID_PARAMETER;
2554         }
2555
2556         if (kbyte == NULL) {
2557                 REC_LOG_ERROR("NULL pointer kbyte");
2558                 return RECORDER_ERROR_INVALID_PARAMETER;
2559         }
2560
2561         REC_LOG_INFO("ENTER");
2562
2563         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2564
2565         if (ret == RECORDER_ERROR_NONE)
2566                 *kbyte = pc->cb_info->get_int_value[_RECORDER_GET_INT_SIZE_LIMIT];
2567
2568         REC_LOG_INFO("ret[0x%x],[%d] kbyte", ret, *kbyte);
2569
2570         return ret;
2571 }
2572
2573
2574 int recorder_attr_get_time_limit(recorder_h recorder, int *second)
2575 {
2576         int ret = RECORDER_ERROR_NONE;
2577         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_TIME_LIMIT;
2578         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2579
2580         if (!pc || !pc->cb_info) {
2581                 REC_LOG_ERROR("NULL handle");
2582                 return RECORDER_ERROR_INVALID_PARAMETER;
2583         }
2584
2585         if (second == NULL) {
2586                 REC_LOG_ERROR("NULL pointer second");
2587                 return RECORDER_ERROR_INVALID_PARAMETER;
2588         }
2589
2590         REC_LOG_INFO("ENTER");
2591
2592         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2593
2594         if (ret == RECORDER_ERROR_NONE)
2595                 *second = pc->cb_info->get_int_value[_RECORDER_GET_INT_TIME_LIMIT];
2596
2597         REC_LOG_INFO("ret[0x%x],[%d] second", ret, *second);
2598
2599         return ret;
2600 }
2601
2602
2603 int recorder_attr_get_audio_device(recorder_h recorder, recorder_audio_device_e *device)
2604 {
2605         int ret = RECORDER_ERROR_NONE;
2606         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_DEVICE;
2607         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2608
2609         if (!pc || !pc->cb_info) {
2610                 REC_LOG_ERROR("NULL handle");
2611                 return RECORDER_ERROR_INVALID_PARAMETER;
2612         }
2613
2614         if (device == NULL) {
2615                 REC_LOG_ERROR("NULL pointer device");
2616                 return RECORDER_ERROR_INVALID_PARAMETER;
2617         }
2618
2619         REC_LOG_INFO("ENTER");
2620
2621         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2622
2623         if (ret == RECORDER_ERROR_NONE)
2624                 *device = (recorder_audio_device_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_DEVICE];
2625
2626         REC_LOG_INFO("ret[0x%x], device[%d]", ret, *device);
2627
2628         return ret;
2629 }
2630
2631
2632 int recorder_attr_get_audio_samplerate(recorder_h recorder, int *samplerate)
2633 {
2634         int ret = RECORDER_ERROR_NONE;
2635         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_SAMPLERATE;
2636         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2637
2638         if (!pc || !pc->cb_info) {
2639                 REC_LOG_ERROR("NULL handle");
2640                 return RECORDER_ERROR_INVALID_PARAMETER;
2641         }
2642
2643         if (samplerate == NULL) {
2644                 REC_LOG_ERROR("NULL pointer handle");
2645                 return RECORDER_ERROR_INVALID_PARAMETER;
2646         }
2647
2648         REC_LOG_INFO("ENTER");
2649
2650         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2651
2652         if (ret == RECORDER_ERROR_NONE)
2653                 *samplerate = pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_SAMPLERATE];
2654
2655         REC_LOG_INFO("ret[0x%x], samplerate[%d]", ret, *samplerate);
2656
2657         return ret;
2658 }
2659
2660
2661 int recorder_attr_get_audio_encoder_bitrate(recorder_h recorder, int *bitrate)
2662 {
2663         int ret = RECORDER_ERROR_NONE;
2664         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_ENCODER_BITRATE;
2665         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2666
2667         if (!pc || !pc->cb_info) {
2668                 REC_LOG_ERROR("NULL handle");
2669                 return RECORDER_ERROR_INVALID_PARAMETER;
2670         }
2671
2672         if (bitrate == NULL) {
2673                 REC_LOG_ERROR("NULL pointer");
2674                 return RECORDER_ERROR_INVALID_PARAMETER;
2675         }
2676
2677         REC_LOG_INFO("ENTER");
2678
2679         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2680
2681         if (ret == RECORDER_ERROR_NONE)
2682                 *bitrate = pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_ENCODER_BITRATE];
2683
2684         REC_LOG_INFO("ret[0x%x], bitrate[%d]", ret, *bitrate);
2685
2686         return ret;
2687 }
2688
2689
2690 int recorder_attr_get_video_encoder_bitrate(recorder_h recorder, int *bitrate)
2691 {
2692         int ret = RECORDER_ERROR_NONE;
2693         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_VIDEO_ENCODER_BITRATE;
2694         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2695
2696         if (!pc || !pc->cb_info) {
2697                 REC_LOG_ERROR("NULL handle");
2698                 return RECORDER_ERROR_INVALID_PARAMETER;
2699         }
2700
2701         if (bitrate == NULL) {
2702                 REC_LOG_ERROR("NULL pointer");
2703                 return RECORDER_ERROR_INVALID_PARAMETER;
2704         }
2705
2706         REC_LOG_INFO("ENTER");
2707
2708         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2709
2710         if (ret == RECORDER_ERROR_NONE)
2711                 *bitrate = pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_ENCODER_BITRATE];
2712
2713         REC_LOG_INFO("ret[0x%x]", ret);
2714
2715         return ret;
2716 }
2717
2718
2719 int recorder_foreach_supported_audio_encoder(recorder_h recorder, recorder_supported_audio_encoder_cb foreach_cb, void *user_data)
2720 {
2721         int ret = RECORDER_ERROR_NONE;
2722         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2723         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_AUDIO_ENCODER;
2724
2725         if (!pc || !pc->cb_info || foreach_cb == NULL) {
2726                 REC_LOG_ERROR("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2727                 return RECORDER_ERROR_INVALID_PARAMETER;
2728         }
2729
2730         REC_LOG_INFO("Enter, handle[%td]", pc->remote_handle);
2731
2732         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_AUDIO_ENCODER] = foreach_cb;
2733         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_AUDIO_ENCODER] = user_data;
2734
2735         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2736
2737         REC_LOG_INFO("ret[0x%x]", ret);
2738
2739         return ret;
2740 }
2741
2742
2743 int recorder_foreach_supported_video_encoder(recorder_h recorder, recorder_supported_video_encoder_cb foreach_cb, void *user_data)
2744 {
2745         int ret = RECORDER_ERROR_NONE;
2746         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2747         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_VIDEO_ENCODER;
2748
2749         if (!pc || !pc->cb_info || foreach_cb == NULL) {
2750                 REC_LOG_ERROR("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2751                 return RECORDER_ERROR_INVALID_PARAMETER;
2752         }
2753
2754         REC_LOG_INFO("Enter, handle[%td]", pc->remote_handle);
2755
2756         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_ENCODER] = foreach_cb;
2757         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_ENCODER] = user_data;
2758
2759         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2760
2761         REC_LOG_INFO("ret[0x%x]", ret);
2762
2763         return ret;
2764 }
2765
2766
2767 int recorder_attr_set_mute(recorder_h recorder, bool enable)
2768 {
2769         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_MUTE, "set_enable", enable);
2770 }
2771
2772
2773 bool recorder_attr_is_muted(recorder_h recorder)
2774 {
2775         int ret = false;
2776         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_IS_MUTED;
2777         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2778
2779         if (!pc || !pc->cb_info) {
2780                 REC_LOG_ERROR("NULL handle");
2781                 return false;
2782         }
2783
2784         REC_LOG_INFO("ENTER");
2785
2786         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2787
2788         if (ret == RECORDER_ERROR_SERVICE_DISCONNECTED)
2789                 ret = false;
2790
2791         REC_LOG_INFO("ret[%d]", ret);
2792
2793         return (bool)ret;
2794 }
2795
2796
2797 int recorder_attr_set_recording_motion_rate(recorder_h recorder, double rate)
2798 {
2799         int ret = RECORDER_ERROR_NONE;
2800         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_RECORDING_MOTION_RATE;
2801         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2802
2803         if (!pc || !pc->cb_info) {
2804                 REC_LOG_ERROR("NULL handle");
2805                 return RECORDER_ERROR_INVALID_PARAMETER;
2806         }
2807
2808         REC_LOG_INFO("ENTER - %.20lf", rate);
2809
2810         _recorder_msg_send_param(api, pc->cb_info, &ret,
2811                 MUSE_TYPE_DOUBLE, "rate", (void *)&rate);
2812
2813         REC_LOG_INFO("ret[0x%x]", ret);
2814
2815         return ret;
2816 }
2817
2818
2819 int recorder_attr_get_recording_motion_rate(recorder_h recorder, double *rate)
2820 {
2821         int ret = RECORDER_ERROR_NONE;
2822         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_RECORDING_MOTION_RATE;
2823         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2824
2825         if (!pc || !pc->cb_info) {
2826                 REC_LOG_ERROR("NULL handle");
2827                 return RECORDER_ERROR_INVALID_PARAMETER;
2828         }
2829
2830         if (rate == NULL) {
2831                 REC_LOG_ERROR("rate is NULL");
2832                 return RECORDER_ERROR_INVALID_PARAMETER;
2833         }
2834
2835         REC_LOG_INFO("ENTER");
2836
2837         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2838         if (ret == RECORDER_ERROR_NONE)
2839                 *rate = pc->cb_info->get_double_value[_RECORDER_GET_DOUBLE_RECORDING_MOTION_RATE];
2840
2841         REC_LOG_INFO("ret[0x%x] - rate %.20lf", ret, *rate);
2842
2843         return ret;
2844 }
2845
2846
2847 int recorder_attr_set_audio_channel(recorder_h recorder, int channel_count)
2848 {
2849         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_AUDIO_CHANNEL, "channel_count", channel_count);
2850 }
2851
2852
2853 int recorder_attr_get_audio_channel(recorder_h recorder, int *channel_count)
2854 {
2855         int ret = RECORDER_ERROR_NONE;
2856         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_CHANNEL;
2857         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2858
2859         if (!pc || !pc->cb_info) {
2860                 REC_LOG_ERROR("NULL handle");
2861                 return RECORDER_ERROR_INVALID_PARAMETER;
2862         }
2863
2864         if (channel_count == NULL) {
2865                 REC_LOG_ERROR("channel_count is NULL");
2866                 return RECORDER_ERROR_INVALID_PARAMETER;
2867         }
2868
2869         REC_LOG_INFO("ENTER");
2870
2871         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2872
2873         if (ret == RECORDER_ERROR_NONE)
2874                 *channel_count = pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_CHANNEL];
2875
2876         REC_LOG_INFO("ret[0x%x], channel count[%d]", ret, *channel_count);
2877
2878         return ret;
2879 }
2880
2881
2882 int recorder_attr_set_orientation_tag(recorder_h recorder, recorder_rotation_e orientation)
2883 {
2884         return _recorder_set_int(recorder, MUSE_RECORDER_API_ATTR_SET_ORIENTATION_TAG, "set_orientation", orientation);
2885 }
2886
2887
2888 int  recorder_attr_get_orientation_tag(recorder_h recorder, recorder_rotation_e *orientation)
2889 {
2890         int ret = RECORDER_ERROR_NONE;
2891         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_ORIENTATION_TAG;
2892         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2893
2894         if (!pc || !pc->cb_info) {
2895                 REC_LOG_ERROR("NULL handle");
2896                 return RECORDER_ERROR_INVALID_PARAMETER;
2897         }
2898
2899         if (orientation == NULL) {
2900                 REC_LOG_ERROR("orientation is NULL");
2901                 return RECORDER_ERROR_INVALID_PARAMETER;
2902         }
2903
2904         REC_LOG_INFO("ENTER");
2905
2906         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2907
2908         if (ret == RECORDER_ERROR_NONE)
2909                 *orientation = (recorder_rotation_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_ORIENTATION_TAG];
2910
2911         REC_LOG_INFO("ret[0x%x], orientation[%d]", ret, *orientation);
2912
2913         return ret;
2914 }
2915
2916
2917 int recorder_get_device_state(recorder_type_e type, recorder_device_state_e *state)
2918 {
2919         int ret = RECORDER_ERROR_NONE;
2920         int sock_fd = -1;
2921         int module_index = -1;
2922         int get_device_state = 0;
2923         char *send_msg = NULL;
2924         char recv_msg[MUSE_RECORDER_MSG_MAX_LENGTH] = {'\0',};
2925
2926         if (!state) {
2927                 REC_LOG_ERROR("NULL pointer");
2928                 return RECORDER_ERROR_INVALID_PARAMETER;
2929         }
2930
2931         REC_LOG_INFO("Enter - type[%d]", type);
2932
2933         sock_fd = muse_client_new();
2934         if (sock_fd < 0) {
2935 //LCOV_EXCL_START
2936                 REC_LOG_ERROR("muse_client_new failed - returned fd[%d]", sock_fd);
2937                 ret = RECORDER_ERROR_INVALID_OPERATION;
2938                 goto _GET_DEVICE_STATE_EXIT;
2939 //LCOV_EXCL_STOP
2940         }
2941
2942         if (muse_client_get_module_index(MODULE_NAME, &module_index) != MM_ERROR_NONE) {
2943                 REC_LOG_ERROR("muse client get module index failed");
2944                 ret = RECORDER_ERROR_INVALID_OPERATION;
2945                 goto _GET_DEVICE_STATE_EXIT;
2946         }
2947
2948         send_msg = muse_core_msg_new(MUSE_RECORDER_API_GET_DEVICE_STATE,
2949                 MUSE_TYPE_INT, "module", module_index,
2950                 MUSE_TYPE_INT, PARAM_RECORDER_TYPE, type,
2951                 NULL);
2952         if (!send_msg) {
2953 //LCOV_EXCL_START
2954                 REC_LOG_ERROR("NULL msg");
2955                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
2956                 goto _GET_DEVICE_STATE_EXIT;
2957 //LCOV_EXCL_STOP
2958         }
2959
2960         REC_LOG_INFO("sock_fd[%d], msg[%s]", sock_fd, send_msg);
2961
2962         ret = muse_core_msg_send(sock_fd, send_msg);
2963
2964         muse_core_msg_free(send_msg);
2965         send_msg = NULL;
2966
2967         if (ret < 0) {
2968 //LCOV_EXCL_START
2969                 REC_LOG_ERROR("send msg failed[%d]", errno);
2970                 ret = RECORDER_ERROR_INVALID_OPERATION;
2971                 goto _GET_DEVICE_STATE_EXIT;
2972 //LCOV_EXCL_STOP
2973         }
2974
2975         ret = muse_core_msg_recv(sock_fd, recv_msg, MUSE_RECORDER_MSG_MAX_LENGTH);
2976         if (ret <= 0) {
2977 //LCOV_EXCL_START
2978                 REC_LOG_ERROR("recv msg failed[%d]", errno);
2979                 ret = RECORDER_ERROR_INVALID_OPERATION;
2980                 goto _GET_DEVICE_STATE_EXIT;
2981 //LCOV_EXCL_STOP
2982         }
2983
2984         if (!muse_recorder_msg_get(ret, recv_msg)) {
2985 //LCOV_EXCL_START
2986                 REC_LOG_ERROR("failed to get return value from msg[%s]", recv_msg);
2987                 ret = RECORDER_ERROR_INVALID_OPERATION;
2988                 goto _GET_DEVICE_STATE_EXIT;
2989 //LCOV_EXCL_STOP
2990         }
2991
2992         if (ret == RECORDER_ERROR_NONE) {
2993                 if (muse_recorder_msg_get(get_device_state, recv_msg)) {
2994                         *state = (recorder_device_state_e)get_device_state;
2995                         REC_LOG_INFO("device type[%d] state[%d]", type, *state);
2996                 } else {
2997                         REC_LOG_ERROR("failed to get device state from msg[%s]", recv_msg);
2998                         ret = RECORDER_ERROR_INVALID_OPERATION;
2999                 }
3000         } else {
3001                 REC_LOG_ERROR("failed[0x%x]", ret);
3002         }
3003
3004 _GET_DEVICE_STATE_EXIT:
3005         if (sock_fd > -1) {
3006                 muse_client_close(sock_fd);
3007                 sock_fd = -1;
3008         }
3009
3010         return ret;
3011 }
3012
3013
3014 int recorder_add_device_state_changed_cb(recorder_device_state_changed_cb callback, void *user_data, int *cb_id)
3015 {
3016         int ret = RECORDER_ERROR_NONE;
3017         recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
3018         recorder_cb_info *info = NULL;
3019
3020         if (!callback || !cb_id) {
3021                 REC_LOG_ERROR("invalid pointer[%p][%p]", callback, cb_id);
3022                 return RECORDER_ERROR_INVALID_PARAMETER;
3023         }
3024
3025         g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
3026
3027         /* check recorder support */
3028         ret = recorder_get_device_state(RECORDER_TYPE_AUDIO, &state);
3029         if (ret != RECORDER_ERROR_NONE) {
3030                 REC_LOG_ERROR("get device state failed");
3031                 g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
3032                 return ret;
3033         }
3034
3035         info = g_new0(recorder_cb_info, 1);
3036         if (!info) {
3037                 REC_LOG_ERROR("info failed");
3038                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
3039                 goto _DONE;
3040         }
3041
3042         info->id = ++g_rec_dev_state_changed_cb_id;
3043         info->callback = (void *)callback;
3044         info->user_data = user_data;
3045
3046         *cb_id = info->id;
3047
3048         /* subscribe dbus signal for camera state change */
3049         if (!g_rec_dev_state_changed_cb_conn) {
3050                 g_rec_dev_state_changed_cb_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
3051                 if (!g_rec_dev_state_changed_cb_conn) {
3052                         REC_LOG_ERROR("failed to get gdbus connection");
3053                         ret = RECORDER_ERROR_INVALID_OPERATION;
3054                         goto _DONE;
3055                 }
3056
3057                 REC_LOG_INFO("subscribe signal[%s][%s][%s]",
3058                         MM_CAMCORDER_DBUS_OBJECT,
3059                         MM_CAMCORDER_DBUS_INTERFACE_RECORDER,
3060                         MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED);
3061
3062                 g_rec_dev_state_changed_cb_subscribe_id = g_dbus_connection_signal_subscribe(g_rec_dev_state_changed_cb_conn,
3063                         NULL, MM_CAMCORDER_DBUS_INTERFACE_RECORDER, MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED, MM_CAMCORDER_DBUS_OBJECT, NULL,
3064                         G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)__recorder_device_state_changed_cb, NULL, NULL);
3065                 if (!g_rec_dev_state_changed_cb_subscribe_id) {
3066                         REC_LOG_ERROR("failed to get gdbus connection");
3067                         ret = RECORDER_ERROR_INVALID_OPERATION;
3068                         goto _DONE;
3069                 }
3070
3071                 REC_LOG_INFO("signal subscribe id[%u]", g_rec_dev_state_changed_cb_subscribe_id);
3072         }
3073
3074         g_rec_dev_state_changed_cb_list = g_list_prepend(g_rec_dev_state_changed_cb_list, (gpointer)info);
3075
3076         REC_LOG_INFO("callback id[%d]", info->id);
3077
3078 _DONE:
3079         if (ret != RECORDER_ERROR_NONE) {
3080 //LCOV_EXCL_START
3081                 if (info) {
3082                         g_free(info);
3083                         info = NULL;
3084                 }
3085
3086                 if (g_rec_dev_state_changed_cb_conn) {
3087                         g_object_unref(g_rec_dev_state_changed_cb_conn);
3088                         g_rec_dev_state_changed_cb_conn = NULL;
3089                 }
3090 //LCOV_EXCL_STOP
3091         }
3092
3093         g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
3094
3095         return ret;
3096 }
3097
3098
3099 int recorder_remove_device_state_changed_cb(int cb_id)
3100 {
3101         int ret = RECORDER_ERROR_NONE;
3102         recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
3103         GList *tmp_list = NULL;
3104         recorder_cb_info *info = NULL;
3105
3106         /* check recorder support */
3107         ret = recorder_get_device_state(RECORDER_TYPE_AUDIO, &state);
3108         if (ret != RECORDER_ERROR_NONE) {
3109                 REC_LOG_ERROR("get device state failed");
3110                 return ret;
3111         }
3112
3113         g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
3114
3115         if (!g_rec_dev_state_changed_cb_list) {
3116                 REC_LOG_ERROR("there is no callback info");
3117                 ret = RECORDER_ERROR_INVALID_OPERATION;
3118                 goto _DONE;
3119         }
3120
3121         tmp_list = g_rec_dev_state_changed_cb_list;
3122
3123         do {
3124                 info = tmp_list->data;
3125                 tmp_list = tmp_list->next;
3126
3127                 if (!info) {
3128                         REC_LOG_WARNING("NULL info");
3129                         continue;
3130                 }
3131
3132                 if (info->id == cb_id) {
3133                         g_rec_dev_state_changed_cb_list = g_list_remove(g_rec_dev_state_changed_cb_list, info);
3134
3135                         g_free(info);
3136                         info = NULL;
3137
3138                         if (!g_rec_dev_state_changed_cb_list) {
3139                                 /* no remained callback */
3140                                 if (g_rec_dev_state_changed_cb_conn) {
3141                                         /* unsubscribe signal */
3142                                         g_dbus_connection_signal_unsubscribe(g_rec_dev_state_changed_cb_conn, g_rec_dev_state_changed_cb_subscribe_id);
3143                                         g_rec_dev_state_changed_cb_subscribe_id = 0;
3144
3145                                         /* unref connection */
3146                                         g_object_unref(g_rec_dev_state_changed_cb_conn);
3147                                         g_rec_dev_state_changed_cb_conn = NULL;
3148                                 }
3149                         }
3150
3151                         REC_LOG_INFO("id[%d] callback removed", cb_id);
3152                         ret = RECORDER_ERROR_NONE;
3153
3154                         goto _DONE;
3155                 }
3156         } while (tmp_list);
3157
3158         REC_LOG_ERROR("id[%d] callback not found", cb_id);
3159         ret = RECORDER_ERROR_INVALID_PARAMETER;
3160
3161 _DONE:
3162         g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
3163
3164         return ret;
3165 }
3166
3167
3168 int _recorder_get_log_level(void)
3169 {
3170         return g_recorder_log_level;
3171 }