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