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