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