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