Correct type for some values
[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] = 1;
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] = 1;
864
865                                         /*LOGD("recorder api %d - return 0x%x", 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) - 1);
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         if (cb_info->api_activating[api] == 0) {
1188                 if (time_out == RECORDER_CB_NO_TIMEOUT) {
1189                         LOGW("wait for api %d", api);
1190                         g_cond_wait(&(cb_info->api_cond[api]), &(cb_info->api_mutex[api]));
1191                         ret = cb_info->api_ret[api];
1192                         cb_info->api_activating[api] = 0;
1193                         LOGW("api %d returned 0x%x", api, ret);
1194                 } else {
1195                         end_time = g_get_monotonic_time() + time_out * G_TIME_SPAN_SECOND;
1196                         if (g_cond_wait_until(&(cb_info->api_cond[api]), &(cb_info->api_mutex[api]), end_time)) {
1197                                 ret = cb_info->api_ret[api];
1198                                 cb_info->api_activating[api] = 0;
1199                                 /*LOGD("return value : 0x%x", ret);*/
1200                         } else {
1201                                 ret = RECORDER_ERROR_INVALID_OPERATION;
1202                                 LOGE("api %d was TIMED OUT!", api);
1203                         }
1204                 }
1205         } else {
1206                 ret = cb_info->api_ret[api];
1207                 cb_info->api_activating[api] = 0;
1208
1209                 /*LOGD("condition is already checked for the api[%d], return[0x%x]", api, ret);*/
1210         }
1211
1212         if (ret != RECORDER_ERROR_NONE)
1213                 LOGE("ERROR : api %d - ret 0x%x", api, ret);
1214
1215         g_mutex_unlock(&(cb_info->api_mutex[api]));
1216
1217         return ret;
1218 }
1219
1220
1221 static int _recorder_msg_send(int api, recorder_cb_info_s *cb_info, int *ret, int timeout)
1222 {
1223         int send_ret = 0;
1224         char *msg = NULL;
1225
1226         if (!cb_info || !ret) {
1227                 LOGE("invalid pointer for api %d - %p %p", api, cb_info, ret);
1228                 return RECORDER_ERROR_INVALID_PARAMETER;
1229         }
1230
1231         msg = muse_core_msg_new(api, NULL);
1232         if (!msg) {
1233                 LOGE("msg creation failed: api %d", api);
1234                 return RECORDER_ERROR_OUT_OF_MEMORY;
1235         }
1236
1237         /*LOGD("send msg %s", msg);*/
1238
1239         if (cb_info->is_server_connected) {
1240                 __recorder_update_api_waiting(cb_info, api, 1);
1241                 send_ret = muse_core_msg_send(cb_info->fd, msg);
1242         }
1243
1244         if (send_ret < 0) {
1245                 LOGE("message send failed");
1246                 *ret = RECORDER_ERROR_INVALID_OPERATION;
1247         } else {
1248                 *ret = _recorder_client_wait_for_cb_return(api, cb_info, timeout);
1249         }
1250
1251         __recorder_update_api_waiting(cb_info, api, -1);
1252
1253         muse_core_msg_free(msg);
1254
1255         return RECORDER_ERROR_NONE;
1256 }
1257
1258
1259 static int _recorder_msg_send_param1(int api, recorder_cb_info_s *cb_info, int *ret, recorder_msg_param *param)
1260 {
1261         int send_ret = 0;
1262         char *msg = NULL;
1263
1264         if (!cb_info || !ret || !param) {
1265                 LOGE("invalid pointer for api %d - %p %p %p", api, cb_info, ret, param);
1266                 return RECORDER_ERROR_INVALID_PARAMETER;
1267         }
1268
1269         /*LOGD("type %d, name %s", param->type, param->name);*/
1270
1271         switch (param->type) {
1272         case MUSE_TYPE_INT:
1273                 msg = muse_core_msg_new(api, param->type, param->name, param->value.value_INT, NULL);
1274                 break;
1275         case MUSE_TYPE_DOUBLE:
1276                 msg = muse_core_msg_new(api, param->type, param->name, param->value.value_DOUBLE, NULL);
1277                 break;
1278         case MUSE_TYPE_STRING:
1279                 msg = muse_core_msg_new(api, param->type, param->name, param->value.value_STRING, NULL);
1280                 break;
1281         default:
1282                 LOGE("unknown type %d", param->type);
1283                 break;
1284         }
1285
1286         if (!msg) {
1287                 LOGE("msg creation failed: api %d, type %d, param name %s",
1288                         api, param->type, param->name);
1289                 return RECORDER_ERROR_OUT_OF_MEMORY;
1290         }
1291
1292         /*LOGD("send msg %s", msg);*/
1293
1294         if (cb_info->is_server_connected) {
1295                 __recorder_update_api_waiting(cb_info, api, 1);
1296
1297                 send_ret = muse_core_msg_send(cb_info->fd, msg);
1298         }
1299
1300         if (send_ret < 0) {
1301                 LOGE("message send failed");
1302                 *ret = RECORDER_ERROR_INVALID_OPERATION;
1303         } else {
1304                 *ret = _recorder_client_wait_for_cb_return(api, cb_info, RECORDER_CB_TIMEOUT);
1305         }
1306
1307         __recorder_update_api_waiting(cb_info, api, -1);
1308
1309         muse_core_msg_free(msg);
1310
1311         return RECORDER_ERROR_NONE;
1312 }
1313
1314
1315 static void _recorder_client_callback_destroy(recorder_cb_info_s *cb_info)
1316 {
1317         gint i = 0;
1318
1319         g_return_if_fail(cb_info != NULL);
1320
1321         LOGD("MSG receive thread[%p] destroy", cb_info->msg_recv_thread);
1322
1323         g_thread_join(cb_info->msg_recv_thread);
1324         cb_info->msg_recv_thread = NULL;
1325
1326         LOGD("msg_recv thread removed");
1327
1328         __destroy_msg_handler_thread(&cb_info->msg_handler_info);
1329         __destroy_msg_handler_thread(&cb_info->audio_stream_cb_info);
1330         __destroy_msg_handler_thread(&cb_info->muxed_stream_cb_info);
1331
1332         for (i = 0 ; i < MUSE_RECORDER_EVENT_TYPE_NUM ; i++)
1333                 g_mutex_clear(&cb_info->user_cb_mutex[i]);
1334
1335         for (i = 0 ; i < MUSE_RECORDER_API_MAX ; i++) {
1336                 g_mutex_clear(&cb_info->api_mutex[i]);
1337                 g_cond_clear(&cb_info->api_cond[i]);
1338         }
1339
1340         if (cb_info->fd > -1) {
1341                 muse_client_close(cb_info->fd);
1342                 cb_info->fd = -1;
1343         }
1344
1345         if (cb_info->bufmgr) {
1346                 tbm_bufmgr_deinit(cb_info->bufmgr);
1347                 cb_info->bufmgr = NULL;
1348         }
1349         if (cb_info->get_filename) {
1350                 free(cb_info->get_filename);
1351                 cb_info->get_filename = NULL;
1352         }
1353
1354         g_free(cb_info);
1355         cb_info = NULL;
1356
1357         return;
1358 }
1359
1360
1361 static int _recorder_storage_device_supported_cb(int storage_id, storage_type_e type, storage_state_e state, const char *path, void *user_data)
1362 {
1363         char **root_directory = (char **)user_data;
1364
1365         if (root_directory == NULL) {
1366                 LOGE("user data is NULL");
1367                 return false;
1368         }
1369
1370         LOGD("storage id %d, type %d, state %d, path %s",
1371                 storage_id, type, state, path ? path : "NULL");
1372
1373         if (type == STORAGE_TYPE_INTERNAL && path) {
1374                 if (*root_directory) {
1375                         free(*root_directory);
1376                         *root_directory = NULL;
1377                 }
1378
1379                 *root_directory = strdup(path);
1380                 if (*root_directory) {
1381                         LOGD("get root directory %s", *root_directory);
1382                         return false;
1383                 } else {
1384                         LOGE("strdup %s failed", path);
1385                 }
1386         }
1387
1388         return true;
1389 }
1390
1391 static int _recorder_client_get_root_directory(char **root_directory)
1392 {
1393         int ret = STORAGE_ERROR_NONE;
1394
1395         if (root_directory == NULL) {
1396                 LOGE("user data is NULL");
1397                 return false;
1398         }
1399
1400         ret = storage_foreach_device_supported((storage_device_supported_cb)_recorder_storage_device_supported_cb, root_directory);
1401         if (ret != STORAGE_ERROR_NONE) {
1402                 LOGE("storage_foreach_device_supported failed 0x%x", ret);
1403                 return false;
1404         }
1405
1406         return true;
1407 }
1408
1409 static int _recorder_create_common(recorder_h *recorder, muse_recorder_type_e type, camera_h camera)
1410 {
1411         int ret = RECORDER_ERROR_NONE;
1412         int destroy_ret = RECORDER_ERROR_NONE;
1413         int sock_fd = -1;
1414         int module_index = -1;
1415         int send_ret = 0;
1416         char *send_msg = NULL;
1417         char *root_directory = NULL;
1418         intptr_t camera_handle = 0;
1419         intptr_t handle = 0;
1420         tbm_bufmgr bufmgr = NULL;
1421         recorder_cli_s *pc = NULL;
1422         recorder_msg_param param;
1423
1424         LOGD("Enter - type %d", type);
1425
1426         if (recorder == NULL) {
1427                 LOGE("NULL pointer for recorder handle");
1428                 return RECORDER_ERROR_INVALID_PARAMETER;
1429         }
1430
1431         if (type == MUSE_RECORDER_TYPE_VIDEO && camera == NULL) {
1432                 LOGE("NULL pointer for camera handle on video recorder mode");
1433                 return RECORDER_ERROR_INVALID_PARAMETER;
1434         }
1435
1436         bufmgr = tbm_bufmgr_init(-1);
1437         if (bufmgr == NULL) {
1438                 LOGE("get tbm bufmgr failed");
1439                 return RECORDER_ERROR_INVALID_OPERATION;
1440         }
1441
1442         pc = g_new0(recorder_cli_s, 1);
1443         if (pc == NULL) {
1444                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
1445                 goto _ERR_RECORDER_EXIT;
1446         }
1447
1448         sock_fd = muse_client_new();
1449         if (sock_fd < 0) {
1450 //LCOV_EXCL_START
1451                 LOGE("muse_client_new failed - returned fd %d", sock_fd);
1452                 ret = RECORDER_ERROR_INVALID_OPERATION;
1453                 goto _ERR_RECORDER_EXIT;
1454 //LCOV_EXCL_STOP
1455         }
1456
1457         if (muse_client_get_module_index(MODULE_NAME, &module_index) != MM_ERROR_NONE) {
1458                 LOGE("muse client get module index failed");
1459                 ret = RECORDER_ERROR_INVALID_OPERATION;
1460                 goto _ERR_RECORDER_EXIT;
1461         }
1462
1463         if (type == MUSE_RECORDER_TYPE_AUDIO) {
1464                 send_msg = muse_core_msg_new(MUSE_RECORDER_API_CREATE,
1465                         MUSE_TYPE_INT, "module", module_index,
1466                         MUSE_TYPE_INT, PARAM_RECORDER_TYPE, MUSE_RECORDER_TYPE_AUDIO,
1467                         MUSE_TYPE_INT, "pid", getpid(),
1468                         NULL);
1469         } else {
1470                 pc->camera = camera;
1471                 camera_handle = (intptr_t)((camera_cli_s *)camera)->remote_handle;
1472                 send_msg = muse_core_msg_new(MUSE_RECORDER_API_CREATE,
1473                         MUSE_TYPE_INT, "module", module_index,
1474                         MUSE_TYPE_INT, PARAM_RECORDER_TYPE, MUSE_RECORDER_TYPE_VIDEO,
1475                         MUSE_TYPE_INT, "pid", getpid(),
1476                         MUSE_TYPE_POINTER, "camera_handle", camera_handle,
1477                         NULL);
1478         }
1479
1480         if (!send_msg) {
1481 //LCOV_EXCL_START
1482                 LOGE("NULL msg");
1483                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
1484                 goto _ERR_RECORDER_EXIT;
1485 //LCOV_EXCL_STOP
1486         }
1487
1488         LOGD("sock_fd : %d, msg : %s", sock_fd, send_msg);
1489
1490         send_ret = muse_core_msg_send(sock_fd, send_msg);
1491
1492         muse_core_msg_free(send_msg);
1493         send_msg = NULL;
1494
1495         if (send_ret < 0) {
1496 //LCOV_EXCL_START
1497                 LOGE("send msg failed %d", errno);
1498                 ret = RECORDER_ERROR_INVALID_OPERATION;
1499                 goto _ERR_RECORDER_EXIT;
1500 //LCOV_EXCL_STOP
1501         }
1502
1503         pc->cb_info = _recorder_client_callback_new(sock_fd);
1504         if (pc->cb_info == NULL) {
1505                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
1506                 goto _ERR_RECORDER_EXIT;
1507         }
1508
1509         sock_fd = -1;
1510
1511         ret = _recorder_client_wait_for_cb_return(MUSE_RECORDER_API_CREATE, pc->cb_info, RECORDER_CB_TIMEOUT);
1512
1513         pc->cb_info->api_waiting[MUSE_RECORDER_API_CREATE] = 0;
1514
1515         if (ret != RECORDER_ERROR_NONE) {
1516                 LOGE("API_CREATE failed 0x%x", ret);
1517                 goto _ERR_RECORDER_EXIT;
1518         }
1519
1520         muse_recorder_msg_get_pointer(handle, pc->cb_info->recv_msg);
1521         if (handle == 0) {
1522 //LCOV_EXCL_START
1523                 LOGE("Receiving Handle Failed!!");
1524                 ret = RECORDER_ERROR_INVALID_OPERATION;
1525                 goto _ERR_RECORDER_AFTER_CREATE;
1526 //LCOV_EXCL_STOP
1527         }
1528
1529         if (!_recorder_client_get_root_directory(&root_directory) || root_directory == NULL) {
1530 //LCOV_EXCL_START
1531                 LOGE("failed to get root directory of internal storage");
1532                 ret = RECORDER_ERROR_INVALID_OPERATION;
1533                 goto _ERR_RECORDER_AFTER_CREATE;
1534 //LCOV_EXCL_STOP
1535         }
1536
1537         LOGD("root directory [%s]", root_directory);
1538
1539         RECORDER_MSG_PARAM_SET(param, STRING, root_directory);
1540
1541         _recorder_msg_send_param1(MUSE_RECORDER_API_ATTR_SET_ROOT_DIRECTORY, pc->cb_info, &ret, &param);
1542
1543         if (ret != RECORDER_ERROR_NONE) {
1544                 LOGE("failed to set root directory %s", root_directory);
1545                 ret = RECORDER_ERROR_INVALID_OPERATION;
1546                 goto _ERR_RECORDER_AFTER_CREATE;
1547         }
1548
1549         free(root_directory);
1550         root_directory = NULL;
1551
1552         pc->remote_handle = handle;
1553         pc->cb_info->bufmgr = bufmgr;
1554
1555         LOGD("recorder[type %d] %p create success : remote handle 0x%td",
1556                 type, pc, pc->remote_handle);
1557
1558         *recorder = (recorder_h)pc;
1559
1560         LOGD("done");
1561
1562         return RECORDER_ERROR_NONE;
1563 //LCOV_EXCL_START
1564 _ERR_RECORDER_AFTER_CREATE:
1565         _recorder_msg_send(MUSE_RECORDER_API_DESTROY, pc->cb_info, &destroy_ret, RECORDER_CB_TIMEOUT);
1566         LOGE("destroy return 0x%x", destroy_ret);
1567
1568 _ERR_RECORDER_EXIT:
1569         tbm_bufmgr_deinit(bufmgr);
1570         bufmgr = NULL;
1571
1572         if (root_directory) {
1573                 free(root_directory);
1574                 root_directory = NULL;
1575         }
1576
1577         if (sock_fd > -1) {
1578                 muse_client_close(sock_fd);
1579                 sock_fd = -1;
1580         }
1581
1582         if (pc) {
1583                 if (pc->cb_info) {
1584                         _recorder_client_callback_destroy(pc->cb_info);
1585                         pc->cb_info = NULL;
1586                 }
1587                 g_free(pc);
1588                 pc = NULL;
1589         }
1590
1591         return ret;
1592 //LCOV_EXCL_STOP
1593 }
1594
1595
1596 int recorder_create_videorecorder(camera_h camera, recorder_h *recorder)
1597 {
1598         return _recorder_create_common(recorder, MUSE_RECORDER_TYPE_VIDEO, camera);
1599 }
1600
1601
1602 int recorder_create_audiorecorder(recorder_h *recorder)
1603 {
1604         return _recorder_create_common(recorder, MUSE_RECORDER_TYPE_AUDIO, NULL);
1605 }
1606
1607
1608 int recorder_get_state(recorder_h recorder, recorder_state_e *state)
1609 {
1610         int ret = RECORDER_ERROR_NONE;
1611         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1612         muse_recorder_api_e api = MUSE_RECORDER_API_GET_STATE;
1613
1614         if (!pc || !pc->cb_info) {
1615                 LOGE("NULL handle");
1616                 return RECORDER_ERROR_INVALID_PARAMETER;
1617         }
1618
1619         if (state == NULL) {
1620                 LOGE("NULL pointer state");
1621                 return RECORDER_ERROR_INVALID_PARAMETER;
1622         }
1623
1624         LOGD("Enter, remote_handle : %td", pc->remote_handle);
1625
1626         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1627
1628         if (ret == RECORDER_ERROR_NONE)
1629                 *state = (recorder_state_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_STATE];
1630
1631         LOGD("ret : 0x%x, state : %d", ret, *state);
1632
1633         return ret;
1634 }
1635
1636
1637 int recorder_destroy(recorder_h recorder)
1638 {
1639         int ret = RECORDER_ERROR_NONE;
1640         muse_recorder_api_e api = MUSE_RECORDER_API_DESTROY;
1641         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1642
1643         if (!pc || !pc->cb_info) {
1644                 LOGE("NULL handle");
1645                 return RECORDER_ERROR_INVALID_PARAMETER;
1646         }
1647
1648         LOGD("ENTER");
1649
1650         if (pc->cb_info->is_server_connected)
1651                 _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1652         else
1653                 LOGW("server disconnected. release resource without send message.");
1654
1655         if (ret == RECORDER_ERROR_NONE) {
1656                 _recorder_deactivate_idle_event_all(pc->cb_info);
1657                 _recorder_client_callback_destroy(pc->cb_info);
1658                 g_free(pc);
1659                 pc = NULL;
1660         }
1661
1662         LOGD("ret : 0x%x", ret);
1663
1664         return ret;
1665 }
1666
1667
1668 int recorder_prepare(recorder_h recorder)
1669 {
1670         int ret = RECORDER_ERROR_NONE;
1671         muse_recorder_api_e api = MUSE_RECORDER_API_PREPARE;
1672         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1673
1674         if (!pc || !pc->cb_info) {
1675                 LOGE("NULL handle");
1676                 return RECORDER_ERROR_INVALID_PARAMETER;
1677         }
1678
1679         LOGD("ENTER");
1680
1681         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1682
1683         LOGD("ret : 0x%x", ret);
1684
1685         if (ret == RECORDER_ERROR_NONE && pc->camera)
1686                 camera_start_evas_rendering(pc->camera);
1687
1688         return ret;
1689 }
1690
1691
1692 int recorder_unprepare(recorder_h recorder)
1693 {
1694         int ret = RECORDER_ERROR_NONE;
1695         muse_recorder_api_e api = MUSE_RECORDER_API_UNPREPARE;
1696         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1697         camera_state_e camera_state = CAMERA_STATE_NONE;
1698
1699         if (!pc || !pc->cb_info) {
1700                 LOGE("NULL handle");
1701                 return RECORDER_ERROR_INVALID_PARAMETER;
1702         }
1703
1704         LOGD("ENTER");
1705
1706         if (pc->camera) {
1707 //LCOV_EXCL_START
1708                 ret = camera_get_state(pc->camera, &camera_state);
1709                 if (ret != CAMERA_ERROR_NONE) {
1710                         LOGE("failed to get camera state 0x%x", ret);
1711                         return RECORDER_ERROR_INVALID_OPERATION;
1712                 }
1713
1714                 if (camera_state == CAMERA_STATE_PREVIEW) {
1715                         ret = camera_stop_evas_rendering(pc->camera, false);
1716                         if (ret != CAMERA_ERROR_NONE) {
1717                                 LOGE("camera_stop_evas_rendering failed 0x%x", ret);
1718                                 return RECORDER_ERROR_INVALID_OPERATION;
1719                         }
1720                 }
1721 //LCOV_EXCL_STOP
1722         }
1723
1724         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1725
1726         LOGD("ret : 0x%x", ret);
1727
1728         return ret;
1729 }
1730
1731
1732 int recorder_start(recorder_h recorder)
1733 {
1734         int ret = RECORDER_ERROR_NONE;
1735         muse_recorder_api_e api = MUSE_RECORDER_API_START;
1736         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1737         recorder_state_e current_state = RECORDER_STATE_NONE;
1738
1739         if (!pc || !pc->cb_info) {
1740                 LOGE("NULL handle");
1741                 return RECORDER_ERROR_INVALID_PARAMETER;
1742         }
1743
1744         LOGD("ENTER");
1745
1746         if (pc->camera) {
1747 //LCOV_EXCL_START
1748                 ret = recorder_get_state(recorder, &current_state);
1749                 if (ret != RECORDER_ERROR_NONE) {
1750                         LOGE("failed to get current state 0x%x", ret);
1751                         return RECORDER_ERROR_INVALID_OPERATION;
1752                 }
1753
1754                 if (current_state == RECORDER_STATE_READY) {
1755                         ret = camera_stop_evas_rendering(pc->camera, true);
1756                         if (ret != CAMERA_ERROR_NONE) {
1757                                 LOGE("camera_stop_evas_rendering failed 0x%x", ret);
1758                                 return RECORDER_ERROR_INVALID_OPERATION;
1759                         }
1760                 }
1761 //LCOV_EXCL_STOP
1762         }
1763
1764         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_NO_TIMEOUT);
1765
1766         if (pc->camera && current_state == RECORDER_STATE_READY)
1767                 camera_start_evas_rendering(pc->camera);
1768
1769         LOGD("ret : 0x%x", ret);
1770
1771         return ret;
1772 }
1773
1774
1775 int recorder_pause(recorder_h recorder)
1776 {
1777         int ret = RECORDER_ERROR_NONE;
1778         muse_recorder_api_e api = MUSE_RECORDER_API_PAUSE;
1779         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1780
1781         if (!pc || !pc->cb_info) {
1782                 LOGE("NULL handle");
1783                 return RECORDER_ERROR_INVALID_PARAMETER;
1784         }
1785
1786         LOGD("ENTER");
1787
1788         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1789
1790         LOGD("ret : 0x%x", ret);
1791
1792         return ret;
1793 }
1794
1795
1796 int recorder_commit(recorder_h recorder)
1797 {
1798         int ret = RECORDER_ERROR_NONE;
1799         muse_recorder_api_e api = MUSE_RECORDER_API_COMMIT;
1800         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1801         recorder_state_e current_state = RECORDER_STATE_NONE;
1802
1803         if (!pc || !pc->cb_info) {
1804                 LOGE("NULL handle");
1805                 return RECORDER_ERROR_INVALID_PARAMETER;
1806         }
1807
1808         LOGD("ENTER");
1809
1810         if (pc->camera) {
1811 //LCOV_EXCL_START
1812                 ret = recorder_get_state(recorder, &current_state);
1813                 if (ret != RECORDER_ERROR_NONE) {
1814                         LOGE("failed to get current state 0x%x", ret);
1815                         return RECORDER_ERROR_INVALID_OPERATION;
1816                 }
1817
1818                 if (current_state >= RECORDER_STATE_RECORDING) {
1819                         ret = camera_stop_evas_rendering(pc->camera, true);
1820                         if (ret != CAMERA_ERROR_NONE) {
1821                                 LOGE("camera_stop_evas_rendering failed 0x%x", ret);
1822                                 return RECORDER_ERROR_INVALID_OPERATION;
1823                         }
1824                 }
1825 //LCOV_EXCL_STOP
1826         }
1827
1828         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1829
1830         if (pc->camera && current_state >= RECORDER_STATE_RECORDING)
1831                 camera_start_evas_rendering(pc->camera);
1832
1833         LOGD("ret : 0x%x", ret);
1834
1835         return ret;
1836 }
1837
1838
1839 int recorder_cancel(recorder_h recorder)
1840 {
1841         int ret = RECORDER_ERROR_NONE;
1842         muse_recorder_api_e api = MUSE_RECORDER_API_CANCEL;
1843         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1844         recorder_state_e current_state = RECORDER_STATE_NONE;
1845
1846         if (!pc || !pc->cb_info) {
1847                 LOGE("NULL handle");
1848                 return RECORDER_ERROR_INVALID_PARAMETER;
1849         }
1850
1851         LOGD("ENTER");
1852
1853         if (pc->camera) {
1854                 ret = recorder_get_state(recorder, &current_state);
1855                 if (ret != RECORDER_ERROR_NONE) {
1856                         LOGE("failed to get current state 0x%x", ret);
1857                         return RECORDER_ERROR_INVALID_OPERATION;
1858                 }
1859
1860                 if (current_state >= RECORDER_STATE_RECORDING) {
1861                         ret = camera_stop_evas_rendering(pc->camera, true);
1862                         if (ret != CAMERA_ERROR_NONE) {
1863                                 LOGE("camera_stop_evas_rendering failed 0x%x", ret);
1864                                 return RECORDER_ERROR_INVALID_OPERATION;
1865                         }
1866                 }
1867         }
1868
1869         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1870
1871         if (pc->camera && current_state >= RECORDER_STATE_RECORDING)
1872                 camera_start_evas_rendering(pc->camera);
1873
1874         LOGD("ret : 0x%x", ret);
1875
1876         return ret;
1877 }
1878
1879
1880 int recorder_set_video_resolution(recorder_h recorder, int width, int height)
1881 {
1882         int ret = RECORDER_ERROR_NONE;
1883         int send_ret = 0;
1884         char *send_msg = NULL;
1885         muse_recorder_api_e api = MUSE_RECORDER_API_SET_VIDEO_RESOLUTION;
1886         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1887
1888         if (!pc || !pc->cb_info) {
1889                 LOGE("NULL handle");
1890                 return RECORDER_ERROR_INVALID_PARAMETER;
1891         }
1892
1893         LOGD("ENTER");
1894
1895         send_msg = muse_core_msg_new(api,
1896                 MUSE_TYPE_INT, "width", width,
1897                 MUSE_TYPE_INT, "height", height,
1898                 NULL);
1899         if (send_msg) {
1900                 if (pc->cb_info->is_server_connected) {
1901                         __recorder_update_api_waiting(pc->cb_info, api, 1);
1902
1903                         send_ret = muse_core_msg_send(pc->cb_info->fd, send_msg);
1904                 }
1905
1906                 if (send_ret < 0) {
1907                         LOGE("message send failed");
1908                         ret = RECORDER_ERROR_INVALID_OPERATION;
1909                 } else {
1910                         ret = _recorder_client_wait_for_cb_return(api, pc->cb_info, RECORDER_CB_TIMEOUT);
1911                 }
1912
1913                 __recorder_update_api_waiting(pc->cb_info, api, -1);
1914
1915                 muse_core_msg_free(send_msg);
1916         } else {
1917                 LOGE("failed to create msg");
1918                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
1919         }
1920
1921         LOGD("ret : 0x%x", ret);
1922
1923         return ret;
1924 }
1925
1926
1927 int recorder_get_video_resolution(recorder_h recorder, int *width, int *height)
1928 {
1929         int ret = RECORDER_ERROR_NONE;
1930         muse_recorder_api_e api = MUSE_RECORDER_API_GET_VIDEO_RESOLUTION;
1931         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1932
1933         if (!pc || !pc->cb_info) {
1934                 LOGE("NULL handle");
1935                 return RECORDER_ERROR_INVALID_PARAMETER;
1936         }
1937
1938         if (!width || !height) {
1939                 LOGE("NULL pointer width = [%p], height = [%p]", width, height);
1940                 return RECORDER_ERROR_INVALID_PARAMETER;
1941         }
1942
1943         LOGD("ENTER");
1944
1945         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1946
1947         if (ret == RECORDER_ERROR_NONE) {
1948                 *width = pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_RESOLUTION] >> 16;
1949                 *height = (0x0000ffff & pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_RESOLUTION]);
1950         }
1951
1952         LOGD("ret : 0x%x, %dx%d", ret, *width, *height);
1953
1954         return ret;
1955 }
1956
1957
1958 int recorder_foreach_supported_video_resolution(recorder_h recorder,
1959         recorder_supported_video_resolution_cb foreach_cb, void *user_data)
1960 {
1961         int ret = RECORDER_ERROR_NONE;
1962         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1963         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_VIDEO_RESOLUTION;
1964
1965         if (!pc || !pc->cb_info || foreach_cb == NULL) {
1966                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
1967                 return RECORDER_ERROR_INVALID_PARAMETER;
1968         }
1969
1970         LOGD("Enter, handle :%td", pc->remote_handle);
1971
1972         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_RESOLUTION] = foreach_cb;
1973         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_RESOLUTION] = user_data;
1974
1975         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1976
1977         LOGD("ret : 0x%x", ret);
1978
1979         return ret;
1980 }
1981
1982
1983 int recorder_get_audio_level(recorder_h recorder, double *level)
1984 {
1985         int ret = RECORDER_ERROR_NONE;
1986         muse_recorder_api_e api = MUSE_RECORDER_API_GET_AUDIO_LEVEL;
1987         recorder_cli_s *pc = (recorder_cli_s *)recorder;
1988
1989         if (!pc || !pc->cb_info || level == NULL) {
1990                 LOGE("NULL pointer %p %p", pc, level);
1991                 return RECORDER_ERROR_INVALID_PARAMETER;
1992         }
1993
1994         LOGD("ENTER");
1995
1996         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
1997
1998         if (ret == RECORDER_ERROR_NONE)
1999                 *level = pc->cb_info->get_double_value[_RECORDER_GET_DOUBLE_AUDIO_LEVEL];
2000
2001         LOGD("ret : 0x%x, level %lf", ret, *level);
2002
2003         return ret;
2004 }
2005
2006
2007 int recorder_set_filename(recorder_h recorder, const char *filename)
2008 {
2009         int ret = RECORDER_ERROR_NONE;
2010         size_t length = 0;
2011         muse_recorder_api_e api = MUSE_RECORDER_API_SET_FILENAME;
2012         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2013         recorder_msg_param param;
2014         char set_filename[RECORDER_FILENAME_MAX] = {'\0',};
2015
2016         if (!pc || !pc->cb_info) {
2017                 LOGE("NULL handle");
2018                 return RECORDER_ERROR_INVALID_PARAMETER;
2019         }
2020
2021         if (filename == NULL) {
2022                 LOGE("filename is NULL");
2023                 return RECORDER_ERROR_INVALID_PARAMETER;
2024         }
2025
2026         LOGD("ENTER [%s]", filename);
2027
2028         length = strlen(filename);
2029
2030         if (length >= RECORDER_FILENAME_MAX - 1) {
2031                 LOGE("too long file name [%zu]", length);
2032                 return RECORDER_ERROR_INVALID_PARAMETER;
2033         }
2034
2035         if (storage_get_origin_internal_path(filename, RECORDER_FILENAME_MAX, set_filename) < 0) {
2036                 /* Cannot convert. Use original path. */
2037                 strncpy(set_filename, filename, length + 1);
2038                 pc->cb_info->is_filename_converted = FALSE;
2039         } else {
2040                 /* Converted. Use converted path. */
2041                 LOGD("Converted filename : %s -> %s", filename, set_filename);
2042                 pc->cb_info->is_filename_converted = TRUE;
2043         }
2044
2045         RECORDER_MSG_PARAM_SET(param, STRING, set_filename);
2046
2047         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2048
2049         LOGD("ret : 0x%x", ret);
2050
2051         return ret;
2052 }
2053
2054
2055 int recorder_get_filename(recorder_h recorder,  char **filename)
2056 {
2057         int ret = RECORDER_ERROR_NONE;
2058         muse_recorder_api_e api = MUSE_RECORDER_API_GET_FILENAME;
2059         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2060         char compat_filename[RECORDER_FILENAME_MAX] = {0, };
2061
2062         if (!pc || !pc->cb_info) {
2063                 LOGE("NULL handle");
2064                 return RECORDER_ERROR_INVALID_PARAMETER;
2065         }
2066
2067         if (filename == NULL) {
2068                 LOGE("filename is NULL");
2069                 return RECORDER_ERROR_INVALID_PARAMETER;
2070         }
2071
2072         LOGD("ENTER");
2073
2074         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2075
2076         if (ret == RECORDER_ERROR_NONE) {
2077                 if (pc->cb_info->is_filename_converted == FALSE ||
2078                         storage_get_compat_internal_path(pc->cb_info->get_filename, RECORDER_FILENAME_MAX, compat_filename) < 0) {
2079                         /* Use original path. */
2080                         *filename = pc->cb_info->get_filename;
2081                 } else {
2082                         /* Converted. Use converted path. */
2083                         LOGD("Converted filename : %s -> %s", pc->cb_info->get_filename, compat_filename);
2084                         *filename = strdup(compat_filename);
2085                         free(pc->cb_info->get_filename);
2086                 }
2087
2088                 pc->cb_info->get_filename = NULL;
2089         }
2090
2091         LOGD("ret : 0x%x, filename : [%s]", ret, (*filename) ? *filename : "NULL");
2092
2093         return ret;
2094 }
2095
2096
2097 int recorder_set_file_format(recorder_h recorder, recorder_file_format_e format)
2098 {
2099         int ret = RECORDER_ERROR_NONE;
2100         int set_format = (int)format;
2101         muse_recorder_api_e api = MUSE_RECORDER_API_SET_FILE_FORMAT;
2102         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2103         recorder_msg_param param;
2104
2105         if (!pc || !pc->cb_info) {
2106                 LOGE("NULL handle");
2107                 return RECORDER_ERROR_INVALID_PARAMETER;
2108         }
2109
2110         LOGD("ENTER, set_format : %d", set_format);
2111
2112         RECORDER_MSG_PARAM_SET(param, INT, set_format);
2113
2114         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2115
2116         LOGD("ret : 0x%x", ret);
2117         return ret;
2118 }
2119
2120
2121 int recorder_get_file_format(recorder_h recorder, recorder_file_format_e *format)
2122 {
2123         int ret = RECORDER_ERROR_NONE;
2124         muse_recorder_api_e api = MUSE_RECORDER_API_GET_FILE_FORMAT;
2125         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2126
2127         if (!pc || !pc->cb_info) {
2128                 LOGE("NULL handle");
2129                 return RECORDER_ERROR_INVALID_PARAMETER;
2130         }
2131
2132         if (format == NULL) {
2133                 LOGE("NULL pointer data");
2134                 return RECORDER_ERROR_INVALID_PARAMETER;
2135         }
2136
2137         LOGD("ENTER");
2138
2139         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2140
2141         if (ret == RECORDER_ERROR_NONE)
2142                 *format = (recorder_file_format_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_FILE_FORMAT];
2143
2144         LOGD("ret : 0x%x, format %d", ret, *format);
2145
2146         return ret;
2147 }
2148
2149
2150 int recorder_set_sound_stream_info(recorder_h recorder, sound_stream_info_h stream_info)
2151 {
2152         int ret = RECORDER_ERROR_NONE;
2153         muse_recorder_api_e api = MUSE_RECORDER_API_SET_SOUND_STREAM_INFO;
2154         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2155         bool is_available = false;
2156         int stream_index = 0;
2157         char *stream_type = NULL;
2158         char *send_msg = NULL;
2159         int send_ret = 0;
2160
2161         if (!pc || !pc->cb_info || stream_info == NULL) {
2162                 LOGE("NULL handle");
2163                 return RECORDER_ERROR_INVALID_PARAMETER;
2164         }
2165
2166         LOGD("ENTER");
2167
2168         ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_RECORDER, &is_available);
2169         if (ret != SOUND_MANAGER_ERROR_NONE) {
2170                 LOGE("stream info verification failed");
2171                 return RECORDER_ERROR_INVALID_OPERATION;
2172         }
2173
2174         if (is_available == false) {
2175                 LOGE("stream information is not available");
2176                 return RECORDER_ERROR_INVALID_OPERATION;
2177         }
2178
2179         ret = sound_manager_get_type_from_stream_information(stream_info, &stream_type);
2180         ret |= sound_manager_get_index_from_stream_information(stream_info, &stream_index);
2181
2182         LOGD("sound manager return [0x%x]", ret);
2183
2184         if (ret == SOUND_MANAGER_ERROR_NONE) {
2185                 send_msg = muse_core_msg_new(api,
2186                         MUSE_TYPE_STRING, "stream_type", stream_type,
2187                         MUSE_TYPE_INT, "stream_index", stream_index,
2188                         NULL);
2189                 if (send_msg) {
2190                         if (pc->cb_info->is_server_connected) {
2191                                 __recorder_update_api_waiting(pc->cb_info, api, 1);
2192
2193                                 send_ret = muse_core_msg_send(pc->cb_info->fd, send_msg);
2194                         }
2195
2196                         if (send_ret < 0) {
2197                                 LOGE("message send failed");
2198                                 ret = RECORDER_ERROR_INVALID_OPERATION;
2199                         } else {
2200                                 ret = _recorder_client_wait_for_cb_return(api, pc->cb_info, RECORDER_CB_TIMEOUT);
2201                         }
2202
2203                         __recorder_update_api_waiting(pc->cb_info, api, -1);
2204
2205                         muse_core_msg_free(send_msg);
2206                 } else {
2207                         LOGE("failed to create msg");
2208                         ret = RECORDER_ERROR_OUT_OF_MEMORY;
2209                 }
2210         } else {
2211                 ret = RECORDER_ERROR_INVALID_OPERATION;
2212         }
2213
2214         return ret;
2215 }
2216
2217
2218 int recorder_set_state_changed_cb(recorder_h recorder, recorder_state_changed_cb callback, void *user_data)
2219 {
2220         int ret = RECORDER_ERROR_NONE;
2221         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2222         muse_recorder_api_e api = MUSE_RECORDER_API_SET_STATE_CHANGED_CB;
2223
2224         if (!pc || !pc->cb_info || callback == NULL) {
2225                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2226                 return RECORDER_ERROR_INVALID_PARAMETER;
2227         }
2228
2229         LOGD("Enter, handle :%td", pc->remote_handle);
2230
2231         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2232
2233         if (ret == RECORDER_ERROR_NONE) {
2234                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
2235
2236                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = callback;
2237                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = user_data;
2238
2239                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
2240         }
2241
2242         LOGD("ret : 0x%x", ret);
2243
2244         return ret;
2245 }
2246
2247
2248 int recorder_unset_state_changed_cb(recorder_h recorder)
2249 {
2250         int ret = RECORDER_ERROR_NONE;
2251         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_STATE_CHANGED_CB;
2252         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2253
2254         if (!pc || !pc->cb_info) {
2255                 LOGE("NULL handle");
2256                 return RECORDER_ERROR_INVALID_PARAMETER;
2257         }
2258
2259         LOGD("ENTER");
2260
2261         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2262
2263         if (ret == RECORDER_ERROR_NONE) {
2264                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
2265
2266                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = NULL;
2267                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE] = NULL;
2268
2269                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_STATE_CHANGE]);
2270         }
2271
2272         LOGD("ret : 0x%x", ret);
2273
2274         return ret;
2275 }
2276
2277
2278 int recorder_set_interrupted_cb(recorder_h recorder, recorder_interrupted_cb callback, void *user_data)
2279 {
2280         int ret = RECORDER_ERROR_NONE;
2281         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2282         muse_recorder_api_e api = MUSE_RECORDER_API_SET_INTERRUPTED_CB;
2283
2284         if (!pc || !pc->cb_info || callback == NULL) {
2285                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2286                 return RECORDER_ERROR_INVALID_PARAMETER;
2287         }
2288
2289         LOGD("Enter, handle :%td", pc->remote_handle);
2290
2291         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2292
2293         if (ret == RECORDER_ERROR_NONE) {
2294                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
2295
2296                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = callback;
2297                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = user_data;
2298
2299                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
2300         }
2301
2302         LOGD("ret : 0x%x", ret);
2303
2304         return ret;
2305 }
2306
2307
2308 int recorder_unset_interrupted_cb(recorder_h recorder)
2309 {
2310         int ret = RECORDER_ERROR_NONE;
2311         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_INTERRUPTED_CB;
2312         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2313
2314         if (!pc || !pc->cb_info) {
2315                 LOGE("NULL handle");
2316                 return RECORDER_ERROR_INVALID_PARAMETER;
2317         }
2318
2319         LOGD("ENTER");
2320
2321         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2322
2323         if (ret == RECORDER_ERROR_NONE) {
2324                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
2325
2326                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = NULL;
2327                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED] = NULL;
2328
2329                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPTED]);
2330         }
2331
2332         LOGD("ret : 0x%x", ret);
2333
2334         return ret;
2335 }
2336
2337
2338 int recorder_set_interrupt_started_cb(recorder_h recorder, recorder_interrupt_started_cb callback, void *user_data)
2339 {
2340         int ret = RECORDER_ERROR_NONE;
2341         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2342         muse_recorder_api_e api = MUSE_RECORDER_API_SET_INTERRUPT_STARTED_CB;
2343
2344         if (!pc || !pc->cb_info || callback == NULL) {
2345                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2346                 return RECORDER_ERROR_INVALID_PARAMETER;
2347         }
2348
2349         LOGD("Enter, handle :%td", pc->remote_handle);
2350
2351         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2352
2353         if (ret == RECORDER_ERROR_NONE) {
2354                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
2355
2356                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = callback;
2357                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = user_data;
2358
2359                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
2360         }
2361
2362         LOGD("ret : 0x%x", ret);
2363
2364         return ret;
2365 }
2366
2367
2368 int recorder_unset_interrupt_started_cb(recorder_h recorder)
2369 {
2370         int ret = RECORDER_ERROR_NONE;
2371         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_INTERRUPT_STARTED_CB;
2372         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2373
2374         if (!pc || !pc->cb_info) {
2375                 LOGE("NULL handle");
2376                 return RECORDER_ERROR_INVALID_PARAMETER;
2377         }
2378
2379         LOGD("ENTER");
2380
2381         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2382
2383         if (ret == RECORDER_ERROR_NONE) {
2384                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
2385
2386                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = NULL;
2387                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED] = NULL;
2388
2389                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_INTERRUPT_STARTED]);
2390         }
2391
2392         LOGD("ret : 0x%x", ret);
2393
2394         return ret;
2395 }
2396
2397
2398 int recorder_set_audio_stream_cb(recorder_h recorder, recorder_audio_stream_cb callback, void *user_data)
2399 {
2400         int ret = RECORDER_ERROR_NONE;
2401         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2402         muse_recorder_api_e api = MUSE_RECORDER_API_SET_AUDIO_STREAM_CB;
2403
2404         if (!pc || !pc->cb_info || callback == NULL) {
2405                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2406                 return RECORDER_ERROR_INVALID_PARAMETER;
2407         }
2408
2409         LOGD("Enter, handle :%td", pc->remote_handle);
2410
2411         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2412
2413         if (ret == RECORDER_ERROR_NONE) {
2414                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
2415
2416                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = callback;
2417                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = user_data;
2418
2419                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
2420         }
2421
2422         LOGD("ret : 0x%x", ret);
2423
2424         return ret;
2425 }
2426
2427
2428 int recorder_unset_audio_stream_cb(recorder_h recorder)
2429 {
2430         int ret = RECORDER_ERROR_NONE;
2431         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_AUDIO_STREAM_CB;
2432         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2433
2434         if (!pc || !pc->cb_info) {
2435                 LOGE("NULL handle");
2436                 return RECORDER_ERROR_INVALID_PARAMETER;
2437         }
2438
2439         LOGD("ENTER");
2440
2441         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2442
2443         if (ret == RECORDER_ERROR_NONE) {
2444                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
2445
2446                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = NULL;
2447                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM] = NULL;
2448
2449                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_AUDIO_STREAM]);
2450         }
2451
2452         LOGD("ret : 0x%x", ret);
2453
2454         return ret;
2455 }
2456
2457
2458 int recorder_set_muxed_stream_cb(recorder_h recorder, recorder_muxed_stream_cb callback, void *user_data)
2459 {
2460         int ret = RECORDER_ERROR_NONE;
2461         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2462         muse_recorder_api_e api = MUSE_RECORDER_API_SET_MUXED_STREAM_CB;
2463
2464         if (!pc || !pc->cb_info || !callback) {
2465                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2466                 return RECORDER_ERROR_INVALID_PARAMETER;
2467         }
2468
2469         LOGD("Enter, handle :%td", pc->remote_handle);
2470
2471         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2472
2473         if (ret == RECORDER_ERROR_NONE) {
2474                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
2475
2476                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = callback;
2477                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = user_data;
2478
2479                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
2480         }
2481
2482         LOGD("ret : 0x%x", ret);
2483
2484         return ret;
2485 }
2486
2487
2488 int recorder_unset_muxed_stream_cb(recorder_h recorder)
2489 {
2490         int ret = RECORDER_ERROR_NONE;
2491         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_MUXED_STREAM_CB;
2492         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2493
2494         if (!pc || !pc->cb_info) {
2495                 LOGE("NULL handle");
2496                 return RECORDER_ERROR_INVALID_PARAMETER;
2497         }
2498
2499         LOGD("ENTER");
2500
2501         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2502
2503         if (ret == RECORDER_ERROR_NONE) {
2504                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
2505
2506                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = NULL;
2507                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM] = NULL;
2508
2509                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_MUXED_STREAM]);
2510         }
2511
2512         LOGD("ret : 0x%x", ret);
2513
2514         return ret;
2515 }
2516
2517
2518 int recorder_set_error_cb(recorder_h recorder, recorder_error_cb callback, void *user_data)
2519 {
2520         int ret = RECORDER_ERROR_NONE;
2521         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2522         muse_recorder_api_e api = MUSE_RECORDER_API_SET_ERROR_CB;
2523
2524         if (!pc || !pc->cb_info || callback == NULL) {
2525                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2526                 return RECORDER_ERROR_INVALID_PARAMETER;
2527         }
2528
2529         LOGD("Enter, handle :%td", pc->remote_handle);
2530
2531         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2532
2533         if (ret == RECORDER_ERROR_NONE) {
2534                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
2535
2536                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_ERROR] = callback;
2537                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_ERROR] = user_data;
2538
2539                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
2540         }
2541
2542         LOGD("ret : 0x%x", ret);
2543
2544         return ret;
2545 }
2546
2547
2548 int recorder_unset_error_cb(recorder_h recorder)
2549 {
2550         int ret = RECORDER_ERROR_NONE;
2551         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_ERROR_CB;
2552         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2553
2554         if (!pc || !pc->cb_info) {
2555                 LOGE("NULL handle");
2556                 return RECORDER_ERROR_INVALID_PARAMETER;
2557         }
2558
2559         LOGD("ENTER");
2560
2561         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2562
2563         if (ret == RECORDER_ERROR_NONE) {
2564                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
2565
2566                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_ERROR] = NULL;
2567                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_ERROR] = NULL;
2568
2569                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_ERROR]);
2570         }
2571
2572         LOGD("ret : 0x%x", ret);
2573
2574         return ret;
2575 }
2576
2577
2578 int recorder_set_recording_status_cb(recorder_h recorder, recorder_recording_status_cb callback, void *user_data)
2579 {
2580         int ret = RECORDER_ERROR_NONE;
2581         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2582         muse_recorder_api_e api = MUSE_RECORDER_API_SET_RECORDING_STATUS_CB;
2583
2584         if (!pc || !pc->cb_info || callback == NULL) {
2585                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2586                 return RECORDER_ERROR_INVALID_PARAMETER;
2587         }
2588
2589         LOGD("Enter, handle :%td", pc->remote_handle);
2590
2591         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2592
2593         if (ret == RECORDER_ERROR_NONE) {
2594                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
2595
2596                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = callback;
2597                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = user_data;
2598
2599                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
2600         }
2601
2602         LOGD("ret : 0x%x", ret);
2603
2604         return ret;
2605 }
2606
2607
2608 int recorder_unset_recording_status_cb(recorder_h recorder)
2609 {
2610         int ret = RECORDER_ERROR_NONE;
2611         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_RECORDING_STATUS_CB;
2612         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2613
2614         if (!pc || !pc->cb_info) {
2615                 LOGE("NULL handle");
2616                 return RECORDER_ERROR_INVALID_PARAMETER;
2617         }
2618
2619         LOGD("ENTER");
2620
2621         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2622
2623         if (ret == RECORDER_ERROR_NONE) {
2624                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
2625
2626                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = NULL;
2627                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS] = NULL;
2628
2629                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_STATUS]);
2630         }
2631
2632         LOGD("ret : 0x%x", ret);
2633
2634         return ret;
2635 }
2636
2637
2638 int recorder_set_recording_limit_reached_cb(recorder_h recorder, recorder_recording_limit_reached_cb callback, void *user_data)
2639 {
2640         int ret = RECORDER_ERROR_NONE;
2641         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2642         muse_recorder_api_e api = MUSE_RECORDER_API_SET_RECORDING_LIMIT_REACHED_CB;
2643
2644         if (!pc || !pc->cb_info || callback == NULL) {
2645                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2646                 return RECORDER_ERROR_INVALID_PARAMETER;
2647         }
2648
2649         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2650
2651         if (ret == RECORDER_ERROR_NONE) {
2652                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
2653
2654                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = callback;
2655                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = user_data;
2656
2657                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
2658         }
2659
2660         LOGD("ret : 0x%x", ret);
2661
2662         return ret;
2663 }
2664
2665
2666 int recorder_unset_recording_limit_reached_cb(recorder_h recorder)
2667 {
2668         int ret = RECORDER_ERROR_NONE;
2669         muse_recorder_api_e api = MUSE_RECORDER_API_UNSET_RECORDING_LIMIT_REACHED_CB;
2670         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2671
2672         if (!pc || !pc->cb_info) {
2673                 LOGE("NULL handle");
2674                 return RECORDER_ERROR_INVALID_PARAMETER;
2675         }
2676
2677         LOGD("ENTER");
2678
2679         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2680
2681         if (ret == RECORDER_ERROR_NONE) {
2682                 g_mutex_lock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
2683
2684                 pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = NULL;
2685                 pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED] = NULL;
2686
2687                 g_mutex_unlock(&pc->cb_info->user_cb_mutex[MUSE_RECORDER_EVENT_TYPE_RECORDING_LIMITED]);
2688         }
2689
2690         LOGD("ret : 0x%x", ret);
2691
2692         return ret;
2693 }
2694
2695
2696 int recorder_foreach_supported_file_format(recorder_h recorder, recorder_supported_file_format_cb foreach_cb, void *user_data)
2697 {
2698         int ret = RECORDER_ERROR_NONE;
2699         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2700         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_FILE_FORMAT;
2701
2702         if (!pc || !pc->cb_info || foreach_cb == NULL) {
2703                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
2704                 return RECORDER_ERROR_INVALID_PARAMETER;
2705         }
2706
2707         LOGD("Enter, handle :%td", pc->remote_handle);
2708
2709         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_FILE_FORMAT] = foreach_cb;
2710         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_FILE_FORMAT] = user_data;
2711
2712         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2713
2714         LOGD("ret : 0x%x", ret);
2715
2716         return ret;
2717 }
2718
2719
2720 int recorder_attr_set_size_limit(recorder_h recorder, int kbyte)
2721 {
2722         int ret = RECORDER_ERROR_NONE;
2723         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_SIZE_LIMIT;
2724         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2725         recorder_msg_param param;
2726
2727         if (!pc || !pc->cb_info) {
2728                 LOGE("NULL handle");
2729                 return RECORDER_ERROR_INVALID_PARAMETER;
2730         }
2731
2732         LOGD("ENTER");
2733
2734         RECORDER_MSG_PARAM_SET(param, INT, kbyte);
2735
2736         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2737
2738         LOGD("ret : 0x%x", ret);
2739
2740         return ret;
2741 }
2742
2743
2744 int recorder_attr_set_time_limit(recorder_h recorder, int second)
2745 {
2746         int ret = RECORDER_ERROR_NONE;
2747         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_TIME_LIMIT;
2748         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2749         recorder_msg_param param;
2750
2751         if (!pc || !pc->cb_info) {
2752                 LOGE("NULL handle");
2753                 return RECORDER_ERROR_INVALID_PARAMETER;
2754         }
2755
2756         LOGD("ENTER");
2757
2758         RECORDER_MSG_PARAM_SET(param, INT, second);
2759
2760         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2761
2762         LOGD("ret : 0x%x", ret);
2763
2764         return ret;
2765 }
2766
2767
2768 int recorder_attr_set_audio_device(recorder_h recorder, recorder_audio_device_e device)
2769 {
2770         int ret = RECORDER_ERROR_NONE;
2771         int set_device = (int)device;
2772         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_AUDIO_DEVICE;
2773         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2774         recorder_msg_param param;
2775
2776         if (!pc || !pc->cb_info) {
2777                 LOGE("NULL handle");
2778                 return RECORDER_ERROR_INVALID_PARAMETER;
2779         };
2780
2781         LOGD("ENTER");
2782
2783         RECORDER_MSG_PARAM_SET(param, INT, set_device);
2784
2785         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2786
2787         LOGD("ret : 0x%x", ret);
2788
2789         return ret;
2790 }
2791
2792
2793 int recorder_set_audio_encoder(recorder_h recorder, recorder_audio_codec_e codec)
2794 {
2795         int ret = RECORDER_ERROR_NONE;
2796         int set_codec = (int)codec;
2797         muse_recorder_api_e api = MUSE_RECORDER_API_SET_AUDIO_ENCODER;
2798         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2799         recorder_msg_param param;
2800
2801         if (!pc || !pc->cb_info) {
2802                 LOGE("NULL handle");
2803                 return RECORDER_ERROR_INVALID_PARAMETER;
2804         }
2805
2806         LOGD("ENTER");
2807
2808         RECORDER_MSG_PARAM_SET(param, INT, set_codec);
2809
2810         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2811
2812         LOGD("ret : 0x%x", ret);
2813
2814         return ret;
2815 }
2816
2817
2818 int recorder_get_audio_encoder(recorder_h recorder, recorder_audio_codec_e *codec)
2819 {
2820         int ret = RECORDER_ERROR_NONE;
2821         muse_recorder_api_e api = MUSE_RECORDER_API_GET_AUDIO_ENCODER;
2822         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2823
2824         if (!pc || !pc->cb_info) {
2825                 LOGE("NULL handle");
2826                 return RECORDER_ERROR_INVALID_PARAMETER;
2827         }
2828
2829         if (codec == NULL) {
2830                 LOGE("codec is NULL");
2831                 return RECORDER_ERROR_INVALID_PARAMETER;
2832         }
2833
2834         LOGD("ENTER");
2835
2836         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2837
2838         if (ret == RECORDER_ERROR_NONE)
2839                 *codec = (recorder_audio_codec_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_ENCODER];
2840
2841         LOGD("ret : 0x%x, codec %d", ret, *codec);
2842
2843         return ret;
2844 }
2845
2846
2847 int recorder_set_video_encoder(recorder_h recorder, recorder_video_codec_e codec)
2848 {
2849         int ret = RECORDER_ERROR_NONE;
2850         int set_codec = (int)codec;
2851         muse_recorder_api_e api = MUSE_RECORDER_API_SET_VIDEO_ENCODER;
2852         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2853         recorder_msg_param param;
2854
2855         if (!pc || !pc->cb_info) {
2856                 LOGE("NULL handle");
2857                 return RECORDER_ERROR_INVALID_PARAMETER;
2858         }
2859
2860         LOGD("ENTER");
2861
2862         RECORDER_MSG_PARAM_SET(param, INT, set_codec);
2863
2864         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2865
2866         LOGD("ret : 0x%x", ret);
2867
2868         return ret;
2869 }
2870
2871
2872 int recorder_get_video_encoder(recorder_h recorder, recorder_video_codec_e *codec)
2873 {
2874         int ret = RECORDER_ERROR_NONE;
2875         muse_recorder_api_e api = MUSE_RECORDER_API_GET_VIDEO_ENCODER;
2876         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2877
2878         if (!pc || !pc->cb_info) {
2879                 LOGE("NULL handle");
2880                 return RECORDER_ERROR_INVALID_PARAMETER;
2881         }
2882
2883         if (codec == NULL) {
2884                 LOGE("codec is NULL");
2885                 return RECORDER_ERROR_INVALID_PARAMETER;
2886         }
2887
2888         LOGD("ENTER");
2889
2890         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2891
2892         if (ret == RECORDER_ERROR_NONE)
2893                 *codec = (recorder_video_codec_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_ENCODER];
2894
2895         LOGD("ret : 0x%x, codec %d", ret, *codec);
2896
2897         return ret;
2898 }
2899
2900
2901 int recorder_attr_set_audio_samplerate(recorder_h recorder, int samplerate)
2902 {
2903         int ret = RECORDER_ERROR_NONE;
2904         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_AUDIO_SAMPLERATE;
2905         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2906         recorder_msg_param param;
2907
2908         if (!pc || !pc->cb_info) {
2909                 LOGE("NULL handle");
2910                 return RECORDER_ERROR_INVALID_PARAMETER;
2911         }
2912
2913         LOGD("ENTER, samplerate : %d", samplerate);
2914
2915         RECORDER_MSG_PARAM_SET(param, INT, samplerate);
2916
2917         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2918
2919         LOGD("ret : 0x%x", ret);
2920
2921         return ret;
2922 }
2923
2924
2925 int recorder_attr_set_audio_encoder_bitrate(recorder_h recorder, int bitrate)
2926 {
2927         int ret = RECORDER_ERROR_NONE;
2928         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_AUDIO_ENCODER_BITRATE;
2929         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2930         recorder_msg_param param;
2931
2932         if (!pc || !pc->cb_info) {
2933                 LOGE("NULL handle");
2934                 return RECORDER_ERROR_INVALID_PARAMETER;
2935         }
2936
2937         LOGD("ENTER");
2938
2939         RECORDER_MSG_PARAM_SET(param, INT, bitrate);
2940
2941         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2942
2943         LOGD("ret : 0x%x", ret);
2944
2945         return ret;
2946 }
2947
2948
2949 int recorder_attr_set_video_encoder_bitrate(recorder_h recorder, int bitrate)
2950 {
2951         int ret = RECORDER_ERROR_NONE;
2952         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_VIDEO_ENCODER_BITRATE;
2953         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2954         recorder_msg_param param;
2955
2956         if (!pc || !pc->cb_info) {
2957                 LOGE("NULL handle");
2958                 return RECORDER_ERROR_INVALID_PARAMETER;
2959         }
2960
2961         LOGD("ENTER");
2962
2963         RECORDER_MSG_PARAM_SET(param, INT, bitrate);
2964
2965         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
2966
2967         LOGD("ret : 0x%x", ret);
2968
2969         return ret;
2970 }
2971
2972
2973 int recorder_attr_get_size_limit(recorder_h recorder, int *kbyte)
2974 {
2975         int ret = RECORDER_ERROR_NONE;
2976         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_SIZE_LIMIT;
2977         recorder_cli_s *pc = (recorder_cli_s *)recorder;
2978
2979         if (!pc || !pc->cb_info) {
2980                 LOGE("NULL handle");
2981                 return RECORDER_ERROR_INVALID_PARAMETER;
2982         }
2983
2984         if (kbyte == NULL) {
2985                 LOGE("NULL pointer kbyte");
2986                 return RECORDER_ERROR_INVALID_PARAMETER;
2987         }
2988
2989         LOGD("ENTER");
2990
2991         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
2992
2993         if (ret == RECORDER_ERROR_NONE)
2994                 *kbyte = pc->cb_info->get_int_value[_RECORDER_GET_INT_SIZE_LIMIT];
2995
2996         LOGD("ret : 0x%x, %d kbyte", ret, *kbyte);
2997
2998         return ret;
2999 }
3000
3001
3002 int recorder_attr_get_time_limit(recorder_h recorder, int *second)
3003 {
3004         int ret = RECORDER_ERROR_NONE;
3005         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_TIME_LIMIT;
3006         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3007
3008         if (!pc || !pc->cb_info) {
3009                 LOGE("NULL handle");
3010                 return RECORDER_ERROR_INVALID_PARAMETER;
3011         }
3012
3013         if (second == NULL) {
3014                 LOGE("NULL pointer second");
3015                 return RECORDER_ERROR_INVALID_PARAMETER;
3016         }
3017
3018         LOGD("ENTER");
3019
3020         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3021
3022         if (ret == RECORDER_ERROR_NONE)
3023                 *second = pc->cb_info->get_int_value[_RECORDER_GET_INT_TIME_LIMIT];
3024
3025         LOGD("ret : 0x%x, %d second", ret, *second);
3026
3027         return ret;
3028 }
3029
3030
3031 int recorder_attr_get_audio_device(recorder_h recorder, recorder_audio_device_e *device)
3032 {
3033         int ret = RECORDER_ERROR_NONE;
3034         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_DEVICE;
3035         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3036
3037         if (!pc || !pc->cb_info) {
3038                 LOGE("NULL handle");
3039                 return RECORDER_ERROR_INVALID_PARAMETER;
3040         }
3041
3042         if (device == NULL) {
3043                 LOGE("NULL pointer device");
3044                 return RECORDER_ERROR_INVALID_PARAMETER;
3045         }
3046
3047         LOGD("ENTER");
3048
3049         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3050
3051         if (ret == RECORDER_ERROR_NONE)
3052                 *device = (recorder_audio_device_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_DEVICE];
3053
3054         LOGD("ret : 0x%x, device %d", ret, *device);
3055
3056         return ret;
3057 }
3058
3059
3060 int recorder_attr_get_audio_samplerate(recorder_h recorder, int *samplerate)
3061 {
3062         int ret = RECORDER_ERROR_NONE;
3063         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_SAMPLERATE;
3064         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3065
3066         if (!pc || !pc->cb_info) {
3067                 LOGE("NULL handle");
3068                 return RECORDER_ERROR_INVALID_PARAMETER;
3069         }
3070
3071         if (samplerate == NULL) {
3072                 LOGE("NULL pointer handle");
3073                 return RECORDER_ERROR_INVALID_PARAMETER;
3074         }
3075
3076         LOGD("ENTER");
3077
3078         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3079
3080         if (ret == RECORDER_ERROR_NONE)
3081                 *samplerate = pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_SAMPLERATE];
3082
3083         LOGD("ret : 0x%x, samplerate %d", ret, *samplerate);
3084
3085         return ret;
3086 }
3087
3088
3089 int recorder_attr_get_audio_encoder_bitrate(recorder_h recorder, int *bitrate)
3090 {
3091         int ret = RECORDER_ERROR_NONE;
3092         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_ENCODER_BITRATE;
3093         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3094
3095         if (!pc || !pc->cb_info) {
3096                 LOGE("NULL handle");
3097                 return RECORDER_ERROR_INVALID_PARAMETER;
3098         }
3099
3100         if (bitrate == NULL) {
3101                 LOGE("NULL pointer");
3102                 return RECORDER_ERROR_INVALID_PARAMETER;
3103         }
3104
3105         LOGD("ENTER");
3106
3107         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3108
3109         if (ret == RECORDER_ERROR_NONE)
3110                 *bitrate = pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_ENCODER_BITRATE];
3111
3112         LOGD("ret : 0x%x, bitrate %d", ret, *bitrate);
3113
3114         return ret;
3115 }
3116
3117
3118 int recorder_attr_get_video_encoder_bitrate(recorder_h recorder, int *bitrate)
3119 {
3120         int ret = RECORDER_ERROR_NONE;
3121         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_VIDEO_ENCODER_BITRATE;
3122         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3123
3124         if (!pc || !pc->cb_info) {
3125                 LOGE("NULL handle");
3126                 return RECORDER_ERROR_INVALID_PARAMETER;
3127         }
3128
3129         if (bitrate == NULL) {
3130                 LOGE("NULL pointer");
3131                 return RECORDER_ERROR_INVALID_PARAMETER;
3132         }
3133
3134         LOGD("ENTER");
3135
3136         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3137
3138         if (ret == RECORDER_ERROR_NONE)
3139                 *bitrate = pc->cb_info->get_int_value[_RECORDER_GET_INT_VIDEO_ENCODER_BITRATE];
3140
3141         LOGD("ret : 0x%x", ret);
3142
3143         return ret;
3144 }
3145
3146
3147 int recorder_foreach_supported_audio_encoder(recorder_h recorder, recorder_supported_audio_encoder_cb foreach_cb, void *user_data)
3148 {
3149         int ret = RECORDER_ERROR_NONE;
3150         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3151         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_AUDIO_ENCODER;
3152
3153         if (!pc || !pc->cb_info || foreach_cb == NULL) {
3154                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
3155                 return RECORDER_ERROR_INVALID_PARAMETER;
3156         }
3157
3158         LOGD("Enter, handle :%td", pc->remote_handle);
3159
3160         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_AUDIO_ENCODER] = foreach_cb;
3161         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_AUDIO_ENCODER] = user_data;
3162
3163         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3164
3165         LOGD("ret : 0x%x", ret);
3166
3167         return ret;
3168 }
3169
3170
3171 int recorder_foreach_supported_video_encoder(recorder_h recorder, recorder_supported_video_encoder_cb foreach_cb, void *user_data)
3172 {
3173         int ret = RECORDER_ERROR_NONE;
3174         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3175         muse_recorder_api_e api = MUSE_RECORDER_API_FOREACH_SUPPORTED_VIDEO_ENCODER;
3176
3177         if (!pc || !pc->cb_info || foreach_cb == NULL) {
3178                 LOGE("INVALID_PARAMETER(0x%08x)", RECORDER_ERROR_INVALID_PARAMETER);
3179                 return RECORDER_ERROR_INVALID_PARAMETER;
3180         }
3181
3182         LOGD("Enter, handle :%td", pc->remote_handle);
3183
3184         pc->cb_info->user_cb[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_ENCODER] = foreach_cb;
3185         pc->cb_info->user_data[MUSE_RECORDER_EVENT_TYPE_FOREACH_SUPPORTED_VIDEO_ENCODER] = user_data;
3186
3187         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3188
3189         LOGD("ret : 0x%x", ret);
3190
3191         return ret;
3192 }
3193
3194
3195 int recorder_attr_set_mute(recorder_h recorder, bool enable)
3196 {
3197         int ret = RECORDER_ERROR_NONE;
3198         int set_enable = (int)enable;
3199         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_MUTE;
3200         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3201         recorder_msg_param param;
3202
3203         if (!pc || !pc->cb_info) {
3204                 LOGE("NULL handle");
3205                 return RECORDER_ERROR_INVALID_PARAMETER;
3206         }
3207
3208         LOGD("ENTER");
3209
3210         RECORDER_MSG_PARAM_SET(param, INT, set_enable);
3211
3212         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
3213
3214         LOGD("ret : 0x%x", ret);
3215
3216         return ret;
3217 }
3218
3219
3220 bool recorder_attr_is_muted(recorder_h recorder)
3221 {
3222         int ret = false;
3223         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_IS_MUTED;
3224         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3225
3226         if (!pc || !pc->cb_info) {
3227                 LOGE("NULL handle");
3228                 return false;
3229         }
3230
3231         LOGD("ENTER");
3232
3233         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3234
3235         if (ret == RECORDER_ERROR_SERVICE_DISCONNECTED)
3236                 ret = false;
3237
3238         LOGD("ret : %d", ret);
3239
3240         return (bool)ret;
3241 }
3242
3243
3244 int recorder_attr_set_recording_motion_rate(recorder_h recorder, double rate)
3245 {
3246         int ret = RECORDER_ERROR_NONE;
3247         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_RECORDING_MOTION_RATE;
3248         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3249         recorder_msg_param param;
3250
3251         if (!pc || !pc->cb_info) {
3252                 LOGE("NULL handle");
3253                 return RECORDER_ERROR_INVALID_PARAMETER;
3254         }
3255
3256         LOGD("ENTER - %.20lf", rate);
3257
3258         RECORDER_MSG_PARAM_SET(param, DOUBLE, rate);
3259
3260         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
3261
3262         LOGD("ret : 0x%x", ret);
3263
3264         return ret;
3265 }
3266
3267
3268 int recorder_attr_get_recording_motion_rate(recorder_h recorder, double *rate)
3269 {
3270         int ret = RECORDER_ERROR_NONE;
3271         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_RECORDING_MOTION_RATE;
3272         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3273
3274         if (!pc || !pc->cb_info) {
3275                 LOGE("NULL handle");
3276                 return RECORDER_ERROR_INVALID_PARAMETER;
3277         }
3278
3279         if (rate == NULL) {
3280                 LOGE("rate is NULL");
3281                 return RECORDER_ERROR_INVALID_PARAMETER;
3282         }
3283
3284         LOGD("ENTER");
3285
3286         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3287         if (ret == RECORDER_ERROR_NONE)
3288                 *rate = pc->cb_info->get_double_value[_RECORDER_GET_DOUBLE_RECORDING_MOTION_RATE];
3289
3290         LOGD("ret : 0x%x - rate %.20lf", ret, *rate);
3291
3292         return ret;
3293 }
3294
3295
3296 int recorder_attr_set_audio_channel(recorder_h recorder, int channel_count)
3297 {
3298         int ret = RECORDER_ERROR_NONE;
3299         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_AUDIO_CHANNEL;
3300         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3301         recorder_msg_param param;
3302
3303         if (!pc || !pc->cb_info) {
3304                 LOGE("NULL handle");
3305                 return RECORDER_ERROR_INVALID_PARAMETER;
3306         }
3307
3308         LOGD("ENTER");
3309
3310         RECORDER_MSG_PARAM_SET(param, INT, channel_count);
3311
3312         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
3313
3314         LOGD("ret : 0x%x", ret);
3315
3316         return ret;
3317 }
3318
3319
3320 int recorder_attr_get_audio_channel(recorder_h recorder, int *channel_count)
3321 {
3322         int ret = RECORDER_ERROR_NONE;
3323         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_AUDIO_CHANNEL;
3324         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3325
3326         if (!pc || !pc->cb_info) {
3327                 LOGE("NULL handle");
3328                 return RECORDER_ERROR_INVALID_PARAMETER;
3329         }
3330
3331         if (channel_count == NULL) {
3332                 LOGE("channel_count is NULL");
3333                 return RECORDER_ERROR_INVALID_PARAMETER;
3334         }
3335
3336         LOGD("ENTER");
3337
3338         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3339
3340         if (ret == RECORDER_ERROR_NONE)
3341                 *channel_count = pc->cb_info->get_int_value[_RECORDER_GET_INT_AUDIO_CHANNEL];
3342
3343         LOGD("ret : 0x%x, channel count %d", ret, *channel_count);
3344
3345         return ret;
3346 }
3347
3348
3349 int recorder_attr_set_orientation_tag(recorder_h recorder, recorder_rotation_e orientation)
3350 {
3351         int ret = RECORDER_ERROR_NONE;
3352         int set_orientation = (int)orientation;
3353         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_SET_ORIENTATION_TAG;
3354         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3355         recorder_msg_param param;
3356
3357         if (!pc || !pc->cb_info) {
3358                 LOGE("NULL handle");
3359                 return RECORDER_ERROR_INVALID_PARAMETER;
3360         }
3361
3362         LOGD("ENTER");
3363
3364         RECORDER_MSG_PARAM_SET(param, INT, set_orientation);
3365
3366         _recorder_msg_send_param1(api, pc->cb_info, &ret, &param);
3367
3368         LOGD("ret : 0x%x", ret);
3369
3370         return ret;
3371 }
3372
3373
3374 int  recorder_attr_get_orientation_tag(recorder_h recorder, recorder_rotation_e *orientation)
3375 {
3376         int ret = RECORDER_ERROR_NONE;
3377         muse_recorder_api_e api = MUSE_RECORDER_API_ATTR_GET_ORIENTATION_TAG;
3378         recorder_cli_s *pc = (recorder_cli_s *)recorder;
3379
3380         if (!pc || !pc->cb_info) {
3381                 LOGE("NULL handle");
3382                 return RECORDER_ERROR_INVALID_PARAMETER;
3383         }
3384
3385         if (orientation == NULL) {
3386                 LOGE("orientation is NULL");
3387                 return RECORDER_ERROR_INVALID_PARAMETER;
3388         }
3389
3390         LOGD("ENTER");
3391
3392         _recorder_msg_send(api, pc->cb_info, &ret, RECORDER_CB_TIMEOUT);
3393
3394         if (ret == RECORDER_ERROR_NONE)
3395                 *orientation = (recorder_rotation_e)pc->cb_info->get_int_value[_RECORDER_GET_INT_ORIENTATION_TAG];
3396
3397         LOGD("ret : 0x%x, orientation %d", ret, *orientation);
3398
3399         return ret;
3400 }
3401
3402
3403 int recorder_get_device_state(recorder_type_e type, recorder_device_state_e *state)
3404 {
3405         int ret = RECORDER_ERROR_NONE;
3406         int sock_fd = -1;
3407         int module_index = -1;
3408         int get_device_state = 0;
3409         char *send_msg = NULL;
3410         char recv_msg[MUSE_RECORDER_MSG_MAX_LENGTH] = {'\0',};
3411
3412         if (!state) {
3413                 LOGE("NULL pointer");
3414                 return RECORDER_ERROR_INVALID_PARAMETER;
3415         }
3416
3417         LOGD("Enter - type %d", type);
3418
3419         sock_fd = muse_client_new();
3420         if (sock_fd < 0) {
3421 //LCOV_EXCL_START
3422                 LOGE("muse_client_new failed - returned fd %d", sock_fd);
3423                 ret = RECORDER_ERROR_INVALID_OPERATION;
3424                 goto _GET_DEVICE_STATE_EXIT;
3425 //LCOV_EXCL_STOP
3426         }
3427
3428         if (muse_client_get_module_index(MODULE_NAME, &module_index) != MM_ERROR_NONE) {
3429                 LOGE("muse client get module index failed");
3430                 ret = RECORDER_ERROR_INVALID_OPERATION;
3431                 goto _GET_DEVICE_STATE_EXIT;
3432         }
3433
3434         send_msg = muse_core_msg_new(MUSE_RECORDER_API_GET_DEVICE_STATE,
3435                 MUSE_TYPE_INT, "module", module_index,
3436                 MUSE_TYPE_INT, PARAM_RECORDER_TYPE, type,
3437                 NULL);
3438         if (!send_msg) {
3439 //LCOV_EXCL_START
3440                 LOGE("NULL msg");
3441                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
3442                 goto _GET_DEVICE_STATE_EXIT;
3443 //LCOV_EXCL_STOP
3444         }
3445
3446         LOGD("sock_fd : %d, msg : %s", sock_fd, send_msg);
3447
3448         ret = muse_core_msg_send(sock_fd, send_msg);
3449
3450         muse_core_msg_free(send_msg);
3451         send_msg = NULL;
3452
3453         if (ret < 0) {
3454 //LCOV_EXCL_START
3455                 LOGE("send msg failed %d", errno);
3456                 ret = RECORDER_ERROR_INVALID_OPERATION;
3457                 goto _GET_DEVICE_STATE_EXIT;
3458 //LCOV_EXCL_STOP
3459         }
3460
3461         ret = muse_core_msg_recv(sock_fd, recv_msg, MUSE_RECORDER_MSG_MAX_LENGTH);
3462         if (ret <= 0) {
3463 //LCOV_EXCL_START
3464                 LOGE("recv msg failed %d", errno);
3465                 ret = RECORDER_ERROR_INVALID_OPERATION;
3466                 goto _GET_DEVICE_STATE_EXIT;
3467 //LCOV_EXCL_STOP
3468         }
3469
3470         if (!muse_recorder_msg_get(ret, recv_msg)) {
3471 //LCOV_EXCL_START
3472                 LOGE("failed to get return value from msg [%s]", recv_msg);
3473                 ret = RECORDER_ERROR_INVALID_OPERATION;
3474                 goto _GET_DEVICE_STATE_EXIT;
3475 //LCOV_EXCL_STOP
3476         }
3477
3478         if (ret == RECORDER_ERROR_NONE) {
3479                 if (muse_recorder_msg_get(get_device_state, recv_msg)) {
3480                         *state = (recorder_device_state_e)get_device_state;
3481                         LOGD("device type %d state %d", type, *state);
3482                 } else {
3483                         LOGE("failed to get device state from msg [%s]", recv_msg);
3484                         ret = RECORDER_ERROR_INVALID_OPERATION;
3485                 }
3486         } else {
3487                 LOGE("failed 0x%x", ret);
3488         }
3489
3490 _GET_DEVICE_STATE_EXIT:
3491         if (sock_fd > -1) {
3492                 muse_client_close(sock_fd);
3493                 sock_fd = -1;
3494         }
3495
3496         return ret;
3497 }
3498
3499
3500 int recorder_add_device_state_changed_cb(recorder_device_state_changed_cb callback, void *user_data, int *cb_id)
3501 {
3502         int ret = RECORDER_ERROR_NONE;
3503         recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
3504         recorder_cb_info *info = NULL;
3505
3506         if (!callback || !cb_id) {
3507                 LOGE("invalid pointer %p %p", callback, cb_id);
3508                 return RECORDER_ERROR_INVALID_PARAMETER;
3509         }
3510
3511         g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
3512
3513         /* check recorder support */
3514         ret = recorder_get_device_state(RECORDER_TYPE_AUDIO, &state);
3515         if (ret != RECORDER_ERROR_NONE) {
3516                 LOGE("get device state failed");
3517                 g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
3518                 return ret;
3519         }
3520
3521         info = g_new0(recorder_cb_info, 1);
3522         if (!info) {
3523                 LOGE("info failed");
3524                 ret = RECORDER_ERROR_OUT_OF_MEMORY;
3525                 goto _DONE;
3526         }
3527
3528         info->id = ++g_rec_dev_state_changed_cb_id;
3529         info->callback = (void *)callback;
3530         info->user_data = user_data;
3531
3532         *cb_id = info->id;
3533
3534         /* subscribe dbus signal for camera state change */
3535         if (!g_rec_dev_state_changed_cb_conn) {
3536                 g_rec_dev_state_changed_cb_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
3537                 if (!g_rec_dev_state_changed_cb_conn) {
3538                         LOGE("failed to get gdbus connection");
3539                         ret = RECORDER_ERROR_INVALID_OPERATION;
3540                         goto _DONE;
3541                 }
3542
3543                 LOGD("subscribe signal %s - %s - %s",
3544                         MM_CAMCORDER_DBUS_OBJECT,
3545                         MM_CAMCORDER_DBUS_INTERFACE_RECORDER,
3546                         MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED);
3547
3548                 g_rec_dev_state_changed_cb_subscribe_id = g_dbus_connection_signal_subscribe(g_rec_dev_state_changed_cb_conn,
3549                         NULL, MM_CAMCORDER_DBUS_INTERFACE_RECORDER, MM_CAMCORDER_DBUS_SIGNAL_STATE_CHANGED, MM_CAMCORDER_DBUS_OBJECT, NULL,
3550                         G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)__recorder_device_state_changed_cb, NULL, NULL);
3551                 if (!g_rec_dev_state_changed_cb_subscribe_id) {
3552                         LOGE("failed to get gdbus connection");
3553                         ret = RECORDER_ERROR_INVALID_OPERATION;
3554                         goto _DONE;
3555                 }
3556
3557                 LOGD("signal subscribe id %u", g_rec_dev_state_changed_cb_subscribe_id);
3558         }
3559
3560         g_rec_dev_state_changed_cb_list = g_list_prepend(g_rec_dev_state_changed_cb_list, (gpointer)info);
3561
3562         LOGD("callback id %d", info->id);
3563
3564 _DONE:
3565         if (ret != RECORDER_ERROR_NONE) {
3566 //LCOV_EXCL_START
3567                 if (info) {
3568                         g_free(info);
3569                         info = NULL;
3570                 }
3571
3572                 if (g_rec_dev_state_changed_cb_conn) {
3573                         g_object_unref(g_rec_dev_state_changed_cb_conn);
3574                         g_rec_dev_state_changed_cb_conn = NULL;
3575                 }
3576 //LCOV_EXCL_STOP
3577         }
3578
3579         g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
3580
3581         return ret;
3582 }
3583
3584
3585 int recorder_remove_device_state_changed_cb(int cb_id)
3586 {
3587         int ret = RECORDER_ERROR_NONE;
3588         recorder_device_state_e state = RECORDER_DEVICE_STATE_IDLE;
3589         GList *tmp_list = NULL;
3590         recorder_cb_info *info = NULL;
3591
3592         /* check recorder support */
3593         ret = recorder_get_device_state(RECORDER_TYPE_AUDIO, &state);
3594         if (ret != RECORDER_ERROR_NONE) {
3595                 LOGE("get device state failed");
3596                 return ret;
3597         }
3598
3599         g_mutex_lock(&g_rec_dev_state_changed_cb_lock);
3600
3601         if (!g_rec_dev_state_changed_cb_list) {
3602                 LOGE("there is no callback info");
3603                 ret = RECORDER_ERROR_INVALID_OPERATION;
3604                 goto _DONE;
3605         }
3606
3607         tmp_list = g_rec_dev_state_changed_cb_list;
3608
3609         do {
3610                 info = tmp_list->data;
3611                 tmp_list = tmp_list->next;
3612
3613                 if (!info) {
3614                         LOGW("NULL info");
3615                         continue;
3616                 }
3617
3618                 if (info->id == cb_id) {
3619                         g_rec_dev_state_changed_cb_list = g_list_remove(g_rec_dev_state_changed_cb_list, info);
3620
3621                         g_free(info);
3622                         info = NULL;
3623
3624                         if (!g_rec_dev_state_changed_cb_list) {
3625                                 /* no remained callback */
3626                                 if (g_rec_dev_state_changed_cb_conn) {
3627                                         /* unsubscribe signal */
3628                                         g_dbus_connection_signal_unsubscribe(g_rec_dev_state_changed_cb_conn, g_rec_dev_state_changed_cb_subscribe_id);
3629                                         g_rec_dev_state_changed_cb_subscribe_id = 0;
3630
3631                                         /* unref connection */
3632                                         g_object_unref(g_rec_dev_state_changed_cb_conn);
3633                                         g_rec_dev_state_changed_cb_conn = NULL;
3634                                 }
3635                         }
3636
3637                         LOGD("id %d callback removed", cb_id);
3638                         ret = RECORDER_ERROR_NONE;
3639
3640                         goto _DONE;
3641                 }
3642         } while (tmp_list);
3643
3644         LOGE("id %d callback not found", cb_id);
3645         ret = RECORDER_ERROR_INVALID_PARAMETER;
3646
3647 _DONE:
3648         g_mutex_unlock(&g_rec_dev_state_changed_cb_lock);
3649
3650         return ret;
3651 }