Remove useless converting error logic inside of device APIs
[platform/core/api/sound-manager.git] / src / sound_manager_private.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 <sound_manager.h>
18 #include <sound_manager_private.h>
19 #include <mm_sound.h>
20 #include <vconf.h>
21
22 #define STREAM_MEDIA                     "media"
23 #define STREAM_SYSTEM                    "system"
24 #define STREAM_ALARM                     "alarm"
25 #define STREAM_NOTIFICATION              "notification"
26 #define STREAM_VOICE_INFORMATION         "voice-information"
27 #define STREAM_VOICE_RECOGNITION         "voice-recognition"
28 #define STREAM_VOICE_RECOGNITION_SERVICE "voice-recognition-service"
29 #define STREAM_VOIP                      "voip"
30 #define STREAM_CALL_VOICE                "call-voice"
31 #define STREAM_CALL_VIDEO                "call-video"
32 #define STREAM_RINGTONE_VOIP             "ringtone-voip"
33 #define STREAM_RINGTONE_CALL             "ringtone-call"
34 #define STREAM_RINGBACKTONE_CALL         "ringbacktone-call"
35 #define STREAM_EMERGENCY                 "emergency"
36 #define STREAM_SOLO                      "solo"
37 #define STREAM_RADIO                     "radio"
38 #define STREAM_LOOPBACK                  "loopback"
39 #define STREAM_LOOPBACK_MIRRORING        "loopback-mirroring"
40 #define STREAM_COMPRESSED_MEDIA          "compressed-media"
41 #define STREAM_NETWORK_SOURCE_MEDIA      "network-source-media"
42 #define STREAM_EXT_MEDIA                 "ext-media"
43
44 #define DBUS_METHOD_TIMEOUT                                     2000
45
46 #define PA_BUS_NAME                                             "org.pulseaudio.Server"
47
48 #define PA_STREAM_MANAGER_OBJECT_PATH                           "/org/pulseaudio/StreamManager"
49 #define PA_STREAM_MANAGER_INTERFACE                             "org.pulseaudio.StreamManager"
50 #define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO           "GetStreamInfo"
51 #define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES  "SetStreamRouteDevices"
52 #define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION   "SetStreamRouteOption"
53 #define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE   "SetStreamPreferredDevice"
54 #define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE   "GetStreamPreferredDevice"
55 #define PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREEMPTIVE_DEVICE  "SetStreamPreemptiveDevice"
56 #define PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREEMPTIVE_DEVICE  "GetStreamPreemptiveDevice"
57 #define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL      "GetVolumeMaxLevel"
58 #define PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL          "GetVolumeLevel"
59 #define PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL          "SetVolumeLevel"
60 #define PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATIO          "SetVolumeRatio"
61 #define PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE   "GetCurrentVolumeType"
62 #define PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH "GetCurrentMediaRoutingPath"
63 #define PA_STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS       "UpdateFocusStatus"
64 #define PA_STREAM_MANAGER_METHOD_NAME_CHECK_STREAM_EXIST_BY_PID "CheckStreamExistByPid"
65 #define PA_STREAM_MANAGER_METHOD_NAME_ACTIVATE_DUCKING          "ActivateDucking"
66 #define PA_STREAM_MANAGER_METHOD_NAME_GET_DUCKING_STATE         "GetDuckingState"
67 #define PA_STREAM_MANAGER_METHOD_NAME_GET_LASTEST_STREAM_PID    "GetPidOfLatestStream"
68
69 #define PA_DEVICE_MANAGER_OBJECT_PATH                           "/org/pulseaudio/DeviceManager"
70 #define PA_DEVICE_MANAGER_INTERFACE                             "org.pulseaudio.DeviceManager"
71 #define PA_DEVICE_MANAGER_METHOD_NAME_IS_DEVICE_RUNNING_BY_ID   "IsDeviceRunningById"
72 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_FORMATS "GetSupportedSampleFormats"
73 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_FORMAT         "SetSampleFormat"
74 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_FORMAT         "GetSampleFormat"
75 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_RATES   "GetSupportedSampleRates"
76 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_RATE           "SetSampleRate"
77 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_RATE           "GetSampleRate"
78 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_AVOID_RESAMPLING      "SetAvoidResampling"
79 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_AVOID_RESAMPLING      "GetAvoidResampling"
80 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SPECIFIC_STREAM       "SetSpecificStreamOnly"
81 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SPECIFIED_STREAM      "GetSpecifiedStream"
82 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_ACM_MODE              "SetAcmMode"
83
84 #define VCONF_PATH_PREFIX_VOLUME                                "file/private/sound/volume/"
85 #define VCONF_PATH_MAX                                          64
86
87 #define SM_SOUND_TYPE_CHECK(x_sound_type, x_error) \
88 if (!strncmp(x_sound_type, "system", strlen(x_sound_type)) || \
89         !strncmp(x_sound_type, "notification", strlen(x_sound_type)) || \
90         !strncmp(x_sound_type, "alarm", strlen(x_sound_type)) || \
91         !strncmp(x_sound_type, "ringtone", strlen(x_sound_type)) || \
92         !strncmp(x_sound_type, "media", strlen(x_sound_type)) || \
93         !strncmp(x_sound_type, "call", strlen(x_sound_type)) || \
94         !strncmp(x_sound_type, "voip", strlen(x_sound_type)) || \
95         !strncmp(x_sound_type, "voice", strlen(x_sound_type))) \
96         return x_error; \
97
98 #define SM_INTERNAL_SOUND_TYPE_CHECK(x_sound_type, x_error) \
99 if (!strncmp(x_sound_type, "bixby", strlen(x_sound_type))) \
100         return x_error; \
101
102 //LCOV_EXCL_START
103 int _convert_dbus_error(const char *error_msg)
104 {
105         int ret = MM_ERROR_NONE;
106
107         if (!error_msg)
108                 return MM_ERROR_SOUND_INTERNAL;
109
110         if (strstr(error_msg, "InvalidArgument"))
111                 ret = MM_ERROR_INVALID_ARGUMENT;
112         else if (strstr(error_msg, "InvalidOperation"))
113                 ret = MM_ERROR_SOUND_INVALID_OPERATION;
114         else if (strstr(error_msg, "PolicyInternal"))
115                 ret = MM_ERROR_POLICY_INTERNAL;
116         else if (strstr(error_msg, "AccessDenied"))
117                 ret = MM_ERROR_SOUND_PERMISSION_DENIED;
118         else
119                 ret = MM_ERROR_SOUND_INTERNAL;
120
121         LOGE("%s => 0x%x", error_msg, ret);
122
123         return ret;
124 }
125 //LCOV_EXCL_STOP
126
127 int _convert_sound_manager_error_code(const char *func, int code)
128 {
129         int ret = SOUND_MANAGER_ERROR_NONE;
130         char *errorstr = NULL;
131
132         switch (code) {
133         case MM_ERROR_FILE_WRITE:
134         case MM_ERROR_INVALID_HANDLE:
135         case MM_ERROR_SOUND_INVALID_OPERATION:
136                 ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
137                 errorstr = "INVALID_OPERATION";
138                 break;
139         case MM_ERROR_NONE:
140                 ret = SOUND_MANAGER_ERROR_NONE;
141                 errorstr = "ERROR_NONE";
142                 break;
143         case MM_ERROR_INVALID_ARGUMENT:
144         case MM_ERROR_SOUND_INVALID_POINTER:
145                 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
146                 errorstr = "INVALID_PARAMETER";
147                 break;
148         case MM_ERROR_SOUND_PERMISSION_DENIED:
149                 //LCOV_EXCL_START
150                 ret = SOUND_MANAGER_ERROR_PERMISSION_DENIED;
151                 errorstr = "PERMISSION_DENIED";
152                 break;
153                 //LCOV_EXCL_STOP
154         case MM_ERROR_SOUND_NO_DATA:
155                 ret = SOUND_MANAGER_ERROR_NO_DATA;
156                 errorstr = "NO_DATA";
157                 break;
158         case MM_ERROR_SOUND_INTERNAL:
159         case MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY:
160         case MM_ERROR_OUT_OF_MEMORY:
161         case MM_ERROR_SOUND_SERVER_DISCONNECTED:
162                 //LCOV_EXCL_START
163                 ret = SOUND_MANAGER_ERROR_INTERNAL;
164                 errorstr = "INTERNAL";
165                 //LCOV_EXCL_STOP
166                 break;
167         case MM_ERROR_POLICY_DUPLICATED:
168         case MM_ERROR_POLICY_INTERNAL:
169         case MM_ERROR_POLICY_BLOCKED:
170                 ret = SOUND_MANAGER_ERROR_POLICY;
171                 errorstr = "POLICY";
172                 break;
173         case MM_ERROR_SOUND_VOLUME_NO_INSTANCE:
174                 ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
175                 errorstr = "NO_PLAYING_SOUND";
176                 break;
177         case MM_ERROR_NOT_SUPPORT_API:
178                 ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
179                 errorstr = "NOT_SUPPORTED";
180                 break;
181         case MM_ERROR_SOUND_INVALID_STATE:
182                 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
183                 errorstr = "INVALID_STATE";
184                 break;
185         default:
186                 //LCOV_EXCL_START
187                 LOGW("it should not be reached here, this error(0x%x) should be defined.", code);
188                 ret = SOUND_MANAGER_ERROR_INTERNAL;
189                 errorstr = "INTERNAL";
190                 break;
191                 //LCOV_EXCL_STOP
192         }
193         if (ret)
194                 LOGE("[%s] >> leave : %s(0x%08x), mm_error(0x%08x)", func, errorstr, ret, code);
195         else
196                 LOGD("[%s] >> leave : %s(0x%08x)", func, errorstr, ret);
197
198         return ret;
199 }
200
201 int _convert_stream_type(sound_stream_type_e stream_type_enum, char **stream_type)
202 {
203         SM_ARG_CHECK(stream_type);
204
205         switch (stream_type_enum) {
206         case SOUND_STREAM_TYPE_MEDIA:
207                 *stream_type = STREAM_MEDIA;
208                 break;
209         case SOUND_STREAM_TYPE_SYSTEM:
210                 *stream_type = STREAM_SYSTEM;
211                 break;
212         case SOUND_STREAM_TYPE_ALARM:
213                 *stream_type = STREAM_ALARM;
214                 break;
215         case SOUND_STREAM_TYPE_NOTIFICATION:
216                 *stream_type = STREAM_NOTIFICATION;
217                 break;
218         case SOUND_STREAM_TYPE_EMERGENCY:
219                 *stream_type = STREAM_EMERGENCY;
220                 break;
221         case SOUND_STREAM_TYPE_VOICE_INFORMATION:
222                 *stream_type = STREAM_VOICE_INFORMATION;
223                 break;
224         case SOUND_STREAM_TYPE_VOICE_RECOGNITION:
225                 *stream_type = STREAM_VOICE_RECOGNITION;
226                 break;
227         case SOUND_STREAM_TYPE_RINGTONE_VOIP:
228                 *stream_type = STREAM_RINGTONE_VOIP;
229                 break;
230         case SOUND_STREAM_TYPE_VOIP:
231                 *stream_type = STREAM_VOIP;
232                 break;
233         case SOUND_STREAM_TYPE_MEDIA_EXTERNAL_ONLY:
234                 *stream_type = STREAM_EXT_MEDIA;
235                 break;
236         default:
237                 //LCOV_EXCL_START
238                 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
239                 return SOUND_MANAGER_ERROR_INTERNAL;
240                 //LCOV_EXCL_STOP
241         }
242
243         LOGI("stream_type[%s]", *stream_type);
244
245         return SOUND_MANAGER_ERROR_NONE;
246 }
247
248 //LCOV_EXCL_START
249 int _convert_stream_type_for_internal(sound_stream_type_internal_e stream_type_enum, char **stream_type)
250 {
251         SM_ARG_CHECK(stream_type);
252
253         switch (stream_type_enum) {
254         case SOUND_STREAM_TYPE_RINGTONE_CALL:
255                 *stream_type = STREAM_RINGTONE_CALL;
256                 break;
257         case SOUND_STREAM_TYPE_RINGBACKTONE_CALL:
258                 *stream_type = STREAM_RINGBACKTONE_CALL;
259                 break;
260         case SOUND_STREAM_TYPE_VOICE_CALL:
261                 *stream_type = STREAM_CALL_VOICE;
262                 break;
263         case SOUND_STREAM_TYPE_VIDEO_CALL:
264                 *stream_type = STREAM_CALL_VIDEO;
265                 break;
266         case SOUND_STREAM_TYPE_RADIO:
267                 *stream_type = STREAM_RADIO;
268                 break;
269         case SOUND_STREAM_TYPE_LOOPBACK:
270                 *stream_type = STREAM_LOOPBACK;
271                 break;
272         case SOUND_STREAM_TYPE_LOOPBACK_MIRRORING:
273                 *stream_type = STREAM_LOOPBACK_MIRRORING;
274                 break;
275         case SOUND_STREAM_TYPE_SOLO:
276                 *stream_type = STREAM_SOLO;
277                 break;
278         case SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE:
279                 *stream_type = STREAM_VOICE_RECOGNITION_SERVICE;
280                 break;
281         case SOUND_STREAM_TYPE_MEDIA_COMPRESSED:
282                 *stream_type = STREAM_COMPRESSED_MEDIA;
283                 break;
284 #ifndef TIZEN_FEATURE_TV_PROD
285         case SOUND_STREAM_TYPE_MEDIA_NETWORK_SOURCE:
286                 *stream_type = STREAM_NETWORK_SOURCE_MEDIA;
287                 break;
288 #endif
289         default:
290                 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
291                 return SOUND_MANAGER_ERROR_INTERNAL;
292         }
293         LOGI("stream_type_for_internal[%s]", *stream_type);
294
295         return SOUND_MANAGER_ERROR_NONE;
296 }
297
298 void _set_focus_availability(sound_stream_info_s *stream_info)
299 {
300         if (stream_info == NULL || stream_info->stream_type == NULL) {
301                 LOGE("invalid argument");
302                 return;
303         }
304         if (!strncmp(stream_info->stream_type, STREAM_SOLO, SOUND_STREAM_TYPE_LEN) ||
305                 !strncmp(stream_info->stream_type, STREAM_RADIO, SOUND_STREAM_TYPE_LEN) ||
306                 !strncmp(stream_info->stream_type, STREAM_LOOPBACK_MIRRORING, SOUND_STREAM_TYPE_LEN)) {
307                 stream_info->is_focus_unavailable = true;
308                 LOGI("this stream_type[%s] does not support focus", stream_info->stream_type);
309         }
310
311         return;
312 }
313 //LCOV_EXCL_STOP
314
315 int _convert_stream_type_to_change_reason(const char *stream_type, sound_stream_focus_change_reason_e *change_reason)
316 {
317         SM_ARG_CHECK(stream_type);
318         SM_ARG_CHECK(change_reason);
319
320         if (!strncmp(stream_type, STREAM_MEDIA, SOUND_STREAM_TYPE_LEN) ||
321                 !strncmp(stream_type, STREAM_COMPRESSED_MEDIA, SOUND_STREAM_TYPE_LEN) ||
322                 !strncmp(stream_type, STREAM_RADIO, SOUND_STREAM_TYPE_LEN) ||
323                 !strncmp(stream_type, STREAM_LOOPBACK, SOUND_STREAM_TYPE_LEN)) {
324                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
325
326         } else if (!strncmp(stream_type, STREAM_SYSTEM, SOUND_STREAM_TYPE_LEN)) {
327                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM;//LCOV_EXCL_LINE
328
329         } else if (!strncmp(stream_type, STREAM_ALARM, SOUND_STREAM_TYPE_LEN)) {
330                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_ALARM;
331
332         } else if (!strncmp(stream_type, STREAM_NOTIFICATION, SOUND_STREAM_TYPE_LEN)) {
333                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION;
334
335         } else if (!strncmp(stream_type, STREAM_EMERGENCY, SOUND_STREAM_TYPE_LEN)) {
336                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY;//LCOV_EXCL_LINE
337
338         } else if (!strncmp(stream_type, STREAM_VOICE_INFORMATION, SOUND_STREAM_TYPE_LEN)) {
339                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION;//LCOV_EXCL_LINE
340
341         } else if (!strncmp(stream_type, STREAM_VOICE_RECOGNITION, SOUND_STREAM_TYPE_LEN) ||
342                         !strncmp(stream_type, STREAM_VOICE_RECOGNITION_SERVICE, SOUND_STREAM_TYPE_LEN)) {
343                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION;
344
345         } else if (!strncmp(stream_type, STREAM_RINGTONE_VOIP, SOUND_STREAM_TYPE_LEN) ||
346                         !strncmp(stream_type, STREAM_RINGTONE_CALL, SOUND_STREAM_TYPE_LEN) ||
347                         !strncmp(stream_type, STREAM_RINGBACKTONE_CALL, SOUND_STREAM_TYPE_LEN)) {
348                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE;
349
350         } else if (!strncmp(stream_type, STREAM_VOIP, SOUND_STREAM_TYPE_LEN)) {
351                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOIP;
352
353         } else if (!strncmp(stream_type, STREAM_CALL_VOICE, SOUND_STREAM_TYPE_LEN) ||
354                         !strncmp(stream_type, STREAM_CALL_VIDEO, SOUND_STREAM_TYPE_LEN)) {
355                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_CALL;//LCOV_EXCL_LINE
356
357         } else if (!strncmp(stream_type, STREAM_EXT_MEDIA, SOUND_STREAM_TYPE_LEN)) {
358                 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY;
359
360         } else {
361                 //LCOV_EXCL_START
362                 LOGE("not supported stream_type(%s)", stream_type);
363                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
364                 //LCOV_EXCL_STOP
365         }
366
367         return SOUND_MANAGER_ERROR_NONE;
368 }
369
370 static int __get_dbus_connection(GDBusConnection **conn)
371 {
372         GError *err = NULL;
373
374         *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
375         if (!(*conn) || err) {
376                 //LCOV_EXCL_START
377                 LOGE("g_bus_get_sync() error (%s)", err ? err->message : NULL);
378                 if (err)
379                         g_error_free(err);
380                 return MM_ERROR_SOUND_INTERNAL;
381                 //LCOV_EXCL_STOP
382         }
383
384         return MM_ERROR_NONE;
385 }
386
387 int _convert_sound_type(sound_type_e sound_type, const char **volume_type)
388 {
389         SM_ARG_CHECK(volume_type);
390
391         switch (sound_type) {
392         case SOUND_TYPE_SYSTEM:
393                 *volume_type = "system";
394                 break;
395         case SOUND_TYPE_NOTIFICATION:
396                 *volume_type = "notification";
397                 break;
398         case SOUND_TYPE_ALARM:
399                 *volume_type = "alarm";
400                 break;
401         case SOUND_TYPE_RINGTONE:
402                 *volume_type = "ringtone";
403                 break;
404         case SOUND_TYPE_MEDIA:
405                 *volume_type = "media";
406                 break;
407         case SOUND_TYPE_CALL:
408                 *volume_type = "call";
409                 break;
410         case SOUND_TYPE_VOIP:
411                 *volume_type = "voip";
412                 break;
413         case SOUND_TYPE_VOICE:
414                 *volume_type = "voice";
415                 break;
416         }
417         LOGI("volume_type[%s]", *volume_type);
418
419         return SOUND_MANAGER_ERROR_NONE;
420 }
421
422 //LCOV_EXCL_START
423 int _convert_sound_type_for_internal(sound_type_internal_e sound_type, const char **volume_type)
424 {
425         SM_ARG_CHECK(volume_type);
426
427         switch (sound_type) {
428         case SOUND_TYPE_BIXBY:
429                 *volume_type = "bixby";
430                 break;
431         }
432         LOGI("volume_type[%s]", *volume_type);
433
434         return SOUND_MANAGER_ERROR_NONE;
435 }
436 //LCOV_EXCL_STOP
437
438 int _convert_sound_type_to_enum(const char *sound_type, sound_type_e *sound_type_enum)
439 {
440         SM_ARG_CHECK(sound_type);
441         SM_ARG_CHECK(sound_type_enum);
442
443         if (!strncmp(sound_type, "system", strlen(sound_type))) {
444                 *sound_type_enum = SOUND_TYPE_SYSTEM;//LCOV_EXCL_LINE
445         } else if (!strncmp(sound_type, "notification", strlen(sound_type))) {
446                 *sound_type_enum = SOUND_TYPE_NOTIFICATION;//LCOV_EXCL_LINE
447         } else if (!strncmp(sound_type, "alarm", strlen(sound_type))) {
448                 *sound_type_enum = SOUND_TYPE_ALARM;
449         } else if (!strncmp(sound_type, "ringtone", strlen(sound_type))) {
450                 *sound_type_enum = SOUND_TYPE_RINGTONE;//LCOV_EXCL_LINE
451         } else if (!strncmp(sound_type, "media", strlen(sound_type))) {
452                 *sound_type_enum = SOUND_TYPE_MEDIA;
453         } else if (!strncmp(sound_type, "call", strlen(sound_type))) {
454                 *sound_type_enum = SOUND_TYPE_CALL;//LCOV_EXCL_LINE
455         } else if (!strncmp(sound_type, "voip", strlen(sound_type))) {
456                 *sound_type_enum = SOUND_TYPE_VOIP;
457         } else if (!strncmp(sound_type, "voice", strlen(sound_type))) {
458                 *sound_type_enum = SOUND_TYPE_VOICE;
459         } else {
460                 //LCOV_EXCL_START
461                 SM_INTERNAL_SOUND_TYPE_CHECK(sound_type, SOUND_MANAGER_ERROR_NO_PLAYING_SOUND);
462                 LOGE("not supported sound_type(%s)", sound_type);
463                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
464                 //LCOV_EXCL_STOP
465         }
466
467         return SOUND_MANAGER_ERROR_NONE;
468 }
469 //LCOV_EXCL_START
470 int _convert_sound_type_to_enum_for_internal(const char *sound_type, sound_type_internal_e *sound_type_enum)
471 {
472         SM_ARG_CHECK(sound_type);
473         SM_ARG_CHECK(sound_type_enum);
474
475         if (!strncmp(sound_type, "bixby", strlen(sound_type))) {
476                 *sound_type_enum = SOUND_TYPE_BIXBY;
477         } else {
478                 SM_SOUND_TYPE_CHECK(sound_type, SOUND_MANAGER_ERROR_NO_PLAYING_SOUND);
479                 LOGE("not supported internal sound_type(%s)", sound_type);
480                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
481         }
482
483         return SOUND_MANAGER_ERROR_NONE;
484 }
485
486 int _convert_device_type_enum_to_str(sound_device_type_e device_type, char **device_type_str)
487 {
488         SM_ARG_CHECK(device_type_str);
489
490         switch (device_type) {
491         case SOUND_DEVICE_BUILTIN_SPEAKER:
492                 *device_type_str = "builtin-speaker";
493                 break;
494         case SOUND_DEVICE_BUILTIN_RECEIVER:
495                 *device_type_str = "builtin-receiver";
496                 break;
497         case SOUND_DEVICE_BUILTIN_MIC:
498                 *device_type_str = "builtin-mic";
499                 break;
500         case SOUND_DEVICE_AUDIO_JACK:
501                 *device_type_str = "audio-jack";
502                 break;
503         case SOUND_DEVICE_BLUETOOTH_MEDIA:
504                 *device_type_str = "bt-a2dp";
505                 break;
506         case SOUND_DEVICE_BLUETOOTH_VOICE:
507                 *device_type_str = "bt-sco";
508                 break;
509         case SOUND_DEVICE_HDMI:
510                 *device_type_str = "hdmi";
511                 break;
512         case SOUND_DEVICE_USB_AUDIO:
513                 *device_type_str = "usb-audio";
514                 break;
515         case SOUND_DEVICE_FORWARDING:
516                 *device_type_str = "forwarding";
517                 break;
518         case SOUND_DEVICE_NETWORK:
519                 *device_type_str = "network";
520                 break;
521         default:
522                 LOGE("could not find the device_type[%d] in this switch case statement", device_type);
523                 return SOUND_MANAGER_ERROR_INTERNAL;
524         }
525
526         LOGI("device_type[%s]", *device_type_str);
527
528         return SOUND_MANAGER_ERROR_NONE;
529 }
530
531 int _convert_device_type_str_to_enum(const char *device_type_str, sound_device_type_e *device_type)
532 {
533         SM_ARG_CHECK(device_type_str);
534         SM_ARG_CHECK(device_type);
535
536         if (!strncmp(device_type_str, "builtin-speaker", SOUND_DEVICE_TYPE_LEN)) {
537                 *device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
538
539         } else if (!strncmp(device_type_str, "builtin-receiver", SOUND_DEVICE_TYPE_LEN)) {
540                 *device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
541
542         } else if (!strncmp(device_type_str, "builtin-mic", SOUND_DEVICE_TYPE_LEN)) {
543                 *device_type = SOUND_DEVICE_BUILTIN_MIC;
544
545         } else if (!strncmp(device_type_str, "audio-jack", SOUND_DEVICE_TYPE_LEN)) {
546                 *device_type = SOUND_DEVICE_AUDIO_JACK;
547         } else if (!strncmp(device_type_str, "hdmi", SOUND_DEVICE_TYPE_LEN)) {
548                 *device_type = SOUND_DEVICE_HDMI;
549
550         } else if (!strncmp(device_type_str, "usb-audio", SOUND_DEVICE_TYPE_LEN)) {
551                 *device_type = SOUND_DEVICE_USB_AUDIO;
552
553         } else if (!strncmp(device_type_str, "bt-a2dp", SOUND_DEVICE_TYPE_LEN)) {
554                 *device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
555
556         } else if (!strncmp(device_type_str, "bt-sco", SOUND_DEVICE_TYPE_LEN)) {
557                 *device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
558
559         } else if (!strncmp(device_type_str, "network", SOUND_DEVICE_TYPE_LEN)) {
560                 *device_type = SOUND_DEVICE_NETWORK;
561
562         } else {
563                 LOGE("not supported device_type(%s)", device_type_str);
564                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
565         }
566
567         return SOUND_MANAGER_ERROR_NONE;
568 }
569 //LCOV_EXCL_STOP
570 int _convert_device_type(mm_sound_device_type_e device_type, sound_device_type_e *sound_device_type)
571 {
572         SM_ARG_CHECK(sound_device_type);
573
574         switch (device_type) {
575         case MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER:
576                 *sound_device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
577                 break;
578         case MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER:
579                 *sound_device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
580                 break;
581         case MM_SOUND_DEVICE_TYPE_BUILTIN_MIC:
582                 *sound_device_type = SOUND_DEVICE_BUILTIN_MIC;
583                 break;
584         //LCOV_EXCL_START
585         case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
586                 *sound_device_type = SOUND_DEVICE_AUDIO_JACK;
587                 break;
588         case MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP:
589                 *sound_device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
590                 break;
591         case MM_SOUND_DEVICE_TYPE_BLUETOOTH_SCO:
592                 *sound_device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
593                 break;
594         case MM_SOUND_DEVICE_TYPE_HDMI:
595                 *sound_device_type = SOUND_DEVICE_HDMI;
596                 break;
597         case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
598                 *sound_device_type = SOUND_DEVICE_USB_AUDIO;
599                 break;
600         case MM_SOUND_DEVICE_TYPE_MIRRORING:
601                 *sound_device_type = SOUND_DEVICE_FORWARDING;
602                 break;
603         case MM_SOUND_DEVICE_TYPE_NETWORK:
604                 *sound_device_type = SOUND_DEVICE_NETWORK;
605                 break;
606         default:
607                 LOGE("not supported device_type(%d)", device_type);
608                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
609         //LCOV_EXCL_STOP
610         }
611
612         return SOUND_MANAGER_ERROR_NONE;
613 }
614
615 int _convert_device_io_direction(mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction)
616 {
617         SM_ARG_CHECK(sound_io_direction);
618
619         switch (io_direction) {
620         case MM_SOUND_DEVICE_IO_DIRECTION_IN:
621                 *sound_io_direction = SOUND_DEVICE_IO_DIRECTION_IN;
622                 break;
623         case MM_SOUND_DEVICE_IO_DIRECTION_OUT:
624                 *sound_io_direction = SOUND_DEVICE_IO_DIRECTION_OUT;
625                 break;
626         case MM_SOUND_DEVICE_IO_DIRECTION_BOTH:
627                 *sound_io_direction = SOUND_DEVICE_IO_DIRECTION_BOTH;
628                 break;
629         }
630
631         return SOUND_MANAGER_ERROR_NONE;
632 }
633 //LCOV_EXCL_START
634 const char* _convert_api_name(native_api_e api_name)
635 {
636         const char* name = NULL;
637
638         switch (api_name) {
639         case NATIVE_API_SOUND_MANAGER:
640                 name = "sound-manager";
641                 break;
642         case NATIVE_API_PLAYER:
643                 name = "player";
644                 break;
645         case NATIVE_API_WAV_PLAYER:
646                 name = "wav-player";
647                 break;
648         case NATIVE_API_TONE_PLAYER:
649                 name = "tone-player";
650                 break;
651         case NATIVE_API_AUDIO_IO:
652                 name = "audio-io";
653                 break;
654         case NATIVE_API_RECORDER:
655                 name = "recorder";
656                 break;
657         }
658
659         return name;
660 }
661
662 int _convert_sample_format_enum_to_str(sound_sample_format_e format, char **format_str)
663 {
664         SM_ARG_CHECK(format_str);
665
666         switch (format) {
667         case SOUND_SAMPLE_FORMAT_U8:
668                 *format_str = "u8";
669                 break;
670         case SOUND_SAMPLE_FORMAT_S16_LE:
671                 *format_str = "s16le";
672                 break;
673         case SOUND_SAMPLE_FORMAT_S24_LE:
674                 *format_str = "s24le";
675                 break;
676         case SOUND_SAMPLE_FORMAT_S24_32_LE:
677                 *format_str = "s24-32le";
678                 break;
679         default:
680                 LOGE("could not find format[%d] in this switch case statement", format);
681                 return SOUND_MANAGER_ERROR_INTERNAL;
682         }
683
684         return SOUND_MANAGER_ERROR_NONE;
685 }
686
687 int _convert_sample_format_str_to_enum(const char *format_str, sound_sample_format_e *format)
688 {
689         SM_ARG_CHECK(format_str);
690         SM_ARG_CHECK(format);
691
692         if (!strncmp(format_str, "u8", SOUND_SAMPLE_FORMAT_LEN) || !strncmp(format_str, "8", SOUND_SAMPLE_FORMAT_LEN)) {
693                 *format = SOUND_SAMPLE_FORMAT_U8;
694         } else if (!strncmp(format_str, "s16le", SOUND_SAMPLE_FORMAT_LEN)) {
695                 *format = SOUND_SAMPLE_FORMAT_S16_LE;
696         } else if (!strncmp(format_str, "s24le", SOUND_SAMPLE_FORMAT_LEN)) {
697                 *format = SOUND_SAMPLE_FORMAT_S24_LE;
698         } else if (!strncmp(format_str, "s24-32le", SOUND_SAMPLE_FORMAT_LEN)) {
699                 *format = SOUND_SAMPLE_FORMAT_S24_32_LE;
700         } else {
701                 LOGE("not supported sample format(%s)", format_str);
702                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
703         }
704
705         return SOUND_MANAGER_ERROR_NONE;
706 }
707
708 int _convert_sample_rate_enum_to_uint(sound_sample_rate_e rate, unsigned int *sample_rate)
709 {
710         SM_ARG_CHECK(sample_rate);
711
712         switch (rate) {
713         case SOUND_SAMPLE_RATE_8000:
714                 *sample_rate = 8000;
715                 break;
716         case SOUND_SAMPLE_RATE_16000:
717                 *sample_rate = 16000;
718                 break;
719         case SOUND_SAMPLE_RATE_22050:
720                 *sample_rate = 22050;
721                 break;
722         case SOUND_SAMPLE_RATE_44100:
723                 *sample_rate = 44100;
724                 break;
725         case SOUND_SAMPLE_RATE_48000:
726                 *sample_rate = 48000;
727                 break;
728         case SOUND_SAMPLE_RATE_88200:
729                 *sample_rate = 88200;
730                 break;
731         case SOUND_SAMPLE_RATE_96000:
732                 *sample_rate = 96000;
733                 break;
734         case SOUND_SAMPLE_RATE_192000:
735                 *sample_rate = 192000;
736                 break;
737         default:
738                 LOGE("not supported sample rate(%u)", rate);
739                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
740         }
741
742         return SOUND_MANAGER_ERROR_NONE;
743 }
744
745 int _convert_sample_rate_to_enum(unsigned int rate, sound_sample_rate_e *rate_e)
746 {
747         SM_ARG_CHECK(rate_e);
748
749         switch (rate) {
750         case 8000:
751                 *rate_e = SOUND_SAMPLE_RATE_8000;
752                 break;
753         case 16000:
754                 *rate_e = SOUND_SAMPLE_RATE_16000;
755                 break;
756         case 22050:
757                 *rate_e = SOUND_SAMPLE_RATE_22050;
758                 break;
759         case 44100:
760                 *rate_e = SOUND_SAMPLE_RATE_44100;
761                 break;
762         case 48000:
763                 *rate_e = SOUND_SAMPLE_RATE_48000;
764                 break;
765         case 88200:
766                 *rate_e = SOUND_SAMPLE_RATE_88200;
767                 break;
768         case 96000:
769                 *rate_e = SOUND_SAMPLE_RATE_96000;
770                 break;
771         case 192000:
772                 *rate_e = SOUND_SAMPLE_RATE_192000;
773                 break;
774         default:
775                 LOGE("not supported sample rate(%u)", rate);
776                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
777         }
778
779         return SOUND_MANAGER_ERROR_NONE;
780 }
781 //LCOV_EXCL_STOP
782
783 int _return_val_if_not_usb_device(sound_device_h device, int ret_val)
784 {
785         mm_sound_device_type_e type;
786
787         if (mm_sound_get_device_type(device, &type))
788                 return ret_val;
789
790         if (type != MM_SOUND_DEVICE_TYPE_USB_AUDIO)     {
791                 LOGE("device type is not USB AUDIO");
792                 return ret_val;
793         }
794
795         return SOUND_MANAGER_ERROR_NONE;
796 }
797
798 //LCOV_EXCL_START
799 void _focus_state_change_callback(int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason, int option, const char *extra_info, void *user_data)
800 {
801         int ret = MM_ERROR_NONE;
802         sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
803         sound_stream_info_s *stream_info;
804
805         LOGI(">> enter");
806
807         if (!user_data) {
808                 LOGE("user_data is null");
809                 goto LEAVE;
810         }
811
812         stream_info = (sound_stream_info_s *)user_data;
813         if (stream_info->focus_id != index) {
814                 LOGE("index is not valid, (%d, %d)", stream_info->focus_id, index);
815                 goto LEAVE;
816         }
817
818         if ((ret = _convert_stream_type_to_change_reason(reason, &change_reason))) {
819                 LOGE("failed to _convert_stream_type_to_enum(), reason(%s), err(0x%08x)", reason, ret);
820                 goto LEAVE;
821         }
822
823         SM_ENTER_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
824
825         if (state == FOCUS_IS_RELEASED)
826                 stream_info->acquired_focus &= ~focus_type;
827         else if (state == FOCUS_IS_ACQUIRED)
828                 stream_info->acquired_focus |= focus_type;
829
830         if (state == FOCUS_IS_ACQUIRED)
831                 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
832
833         LOGI("[FOCUS USER CALLBACK(%p) START]", stream_info->user_cb);
834         stream_info->user_cb((sound_stream_info_h)stream_info, focus_type, state, change_reason,
835                                                 option, extra_info, stream_info->user_data);
836         LOGI("[FOCUS USER CALLBACK(%p) END]", stream_info->user_cb);
837
838         if (state == FOCUS_IS_RELEASED)
839                 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
840
841         if (state == FOCUS_IS_RELEASED)
842                 stream_info->prev_acquired_focus &= ~focus_type;
843         else if (state == FOCUS_IS_ACQUIRED)
844                 stream_info->prev_acquired_focus |= focus_type;
845
846         SM_LEAVE_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
847
848 LEAVE:
849         LOGI("<< leave");
850
851         return;
852 }
853
854 void _focus_watch_callback(int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason, const char *extra_info, void *user_data)
855 {
856         int ret = MM_ERROR_NONE;
857         sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
858         _focus_watch_info_s *watch_info;
859
860         if (!user_data) {
861                 LOGE("user_data is null");
862                 goto LEAVE;
863         }
864
865         watch_info = (_focus_watch_info_s *)user_data;
866         if (watch_info->id != index) {
867                 LOGE("index is not valid, (%d, %d)", watch_info->id, index);
868                 goto LEAVE;
869         }
870
871         if ((ret = _convert_stream_type_to_change_reason(reason, &change_reason))) {
872                 LOGE("failed to _convert_stream_type_to_enum(), reason(%s), err(0x%08x)", reason, ret);
873                 goto LEAVE;
874         }
875
876         LOGI("[FOCUS WATCH USER CALLBACK(%p, id:%d) START]", watch_info->user_cb, index);
877         watch_info->user_cb(index, focus_type, state, change_reason, extra_info, watch_info->user_data);
878         LOGI("[FOCUS WATCH USER CALLBACK(%p) END]", watch_info->user_cb);
879
880 LEAVE:
881         LOGI("<< leave");
882         return;
883 }
884 //LCOV_EXCL_STOP
885
886 void _pa_context_state_cb(pa_context *c, void *userdata)
887 {
888         pa_context_state_t state;
889         sound_pa_info_s *pa_info = (sound_pa_info_s *)userdata;
890
891         assert(c);
892
893         state = pa_context_get_state(c);
894
895         LOGI("[%p] context state = [%d]", pa_info, state);
896
897         if (state == PA_CONTEXT_FAILED) {
898                 pa_info->is_disconnected = true;
899                 LOGE("PA DISCONNECTED");
900         }
901
902         switch (state) {
903         case PA_CONTEXT_READY:
904         case PA_CONTEXT_TERMINATED:
905         case PA_CONTEXT_FAILED:
906                 pa_threaded_mainloop_signal(pa_info->mainloop, 0);
907                 break;
908         case PA_CONTEXT_UNCONNECTED:
909         case PA_CONTEXT_CONNECTING:
910         case PA_CONTEXT_AUTHORIZING:
911         case PA_CONTEXT_SETTING_NAME:
912                 break;
913         }
914
915         return;
916 }
917
918 //LCOV_EXCL_START
919 void _pa_stream_state_cb(pa_stream *s, void * userdata)
920 {
921         pa_stream_state_t state;
922         virtual_sound_stream_info_s *vstream_h = (virtual_sound_stream_info_s*)userdata;
923
924         assert(s);
925
926         state = pa_stream_get_state(s);
927         LOGI("[%p] stream [%d] state = [%d]", vstream_h, pa_stream_get_index(s), state);
928
929         switch (state) {
930         case PA_STREAM_READY:
931         case PA_STREAM_FAILED:
932         case PA_STREAM_TERMINATED:
933                 pa_threaded_mainloop_signal(vstream_h->pa_mainloop, 0);
934                 break;
935         case PA_STREAM_UNCONNECTED:
936         case PA_STREAM_CREATING:
937                 break;
938         }
939
940         return;
941 }
942 //LCOV_EXCL_STOP
943
944 int _get_stream_conf_info(const char *stream_type, stream_conf_info_s *info)
945 {
946         int ret = SOUND_MANAGER_ERROR_NONE;
947         GVariant *result = NULL;
948         GVariant *child = NULL;
949         GDBusConnection *conn = NULL;
950         GError *err = NULL;
951         GVariantIter iter;
952         GVariant *item = NULL;
953         gchar *name = NULL;
954         gsize size = 0;
955         int i = 0;
956
957         assert(stream_type);
958         assert(info);
959
960         if ((ret = __get_dbus_connection(&conn)))
961                 return SOUND_MANAGER_ERROR_INTERNAL;
962
963         result = g_dbus_connection_call_sync(conn,
964                                                         PA_BUS_NAME,
965                                                         PA_STREAM_MANAGER_OBJECT_PATH,
966                                                         PA_STREAM_MANAGER_INTERFACE,
967                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO,
968                                                         g_variant_new("(s)", stream_type),
969                                                         G_VARIANT_TYPE("(vvvvvv)"),
970                                                         G_DBUS_CALL_FLAGS_NONE,
971                                                         DBUS_METHOD_TIMEOUT,
972                                                         NULL,
973                                                         &err);
974         if (!result || err) {
975                 //LCOV_EXCL_START
976                 LOGE("g_dbus_connection_call_sync() for GET_STREAM_INFO error (%s)", err ? err->message : NULL);
977                 if (err)
978                         g_error_free(err);
979                 ret = SOUND_MANAGER_ERROR_INTERNAL;
980                 goto LEAVE;
981                 //LCOV_EXCL_STOP
982         }
983
984         /* get priority */
985         child = g_variant_get_child_value(result, 0);
986         item = g_variant_get_variant(child);
987         info->priority = g_variant_get_int32(item);
988         g_variant_unref(item);
989         g_variant_unref(child);
990         LOGI("priority(%d)", info->priority);
991
992         /* get route type */
993         child = g_variant_get_child_value(result, 1);
994         item = g_variant_get_variant(child);
995         info->route_type = g_variant_get_int32(item);
996         g_variant_unref(item);
997         g_variant_unref(child);
998         LOGI("route_type(%d)", info->route_type);
999
1000         /* get volume types */
1001         child = g_variant_get_child_value(result, 2);
1002         item = g_variant_get_variant(child);
1003         g_variant_iter_init(&iter, item);
1004         while (g_variant_iter_loop(&iter, "&s", &name)) {
1005                 if (name && !strncmp(name, "none", strlen("none")))
1006                         continue;
1007                 /* we use volume type only for out direction */
1008                 if (name) {
1009                         LOGI(" volume-type : %s", name);
1010                         info->volume_type = strdup(name);
1011                         break;
1012                 }
1013         }
1014         g_variant_unref(item);
1015         g_variant_unref(child);
1016
1017         /* get available in-devices */
1018         child = g_variant_get_child_value(result, 3);
1019         item = g_variant_get_variant(child);
1020         size = g_variant_n_children(item);
1021         LOGI("num of avail-in-devices are %"G_GSIZE_FORMAT, size);
1022         g_variant_iter_init(&iter, item);
1023         i = 0;
1024         while (g_variant_iter_loop(&iter, "&s", &name)) {
1025                 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1026                         LOGI(" in-device is [%s], skip it", name);
1027                         break;
1028                 }
1029                 LOGI(" in-device name : %s", name);
1030                 info->avail_in_devices[i++] = strdup(name);
1031         }
1032         g_variant_unref(item);
1033         g_variant_unref(child);
1034
1035         /* get available out-devices */
1036         child = g_variant_get_child_value(result, 4);
1037         item = g_variant_get_variant(child);
1038         size = g_variant_n_children(item);
1039         LOGI("num of avail-out-devices are %"G_GSIZE_FORMAT, size);
1040         g_variant_iter_init(&iter, item);
1041         i = 0;
1042         while (g_variant_iter_loop(&iter, "&s", &name)) {
1043                 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1044                         LOGI(" out-device is [%s], skip it", name);
1045                         break;
1046                 }
1047                 LOGI(" out-device name : %s", name);
1048                 info->avail_out_devices[i++] = strdup(name);
1049         }
1050         g_variant_unref(item);
1051         g_variant_unref(child);
1052
1053         /* get available frameworks */
1054         child = g_variant_get_child_value(result, 5);
1055         item = g_variant_get_variant(child);
1056         size = g_variant_n_children(item);
1057         LOGI("num of avail-frameworks are %"G_GSIZE_FORMAT, size);
1058         g_variant_iter_init(&iter, item);
1059         i = 0;
1060         while (g_variant_iter_loop(&iter, "&s", &name)) {
1061                 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1062                         LOGI(" framework is [%s], skip it", name);//LCOV_EXCL_LINE
1063                         break;
1064                 }
1065                 LOGI(" framework name : %s", name);
1066                 info->avail_frameworks[i++] = strdup(name);
1067         }
1068         g_variant_unref(item);
1069         g_variant_unref(child);
1070
1071         if (info->priority == -1) {
1072                 LOGE("could not find the info of stream type(%s)", stream_type);//LCOV_EXCL_LINE
1073                 ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
1074         }
1075
1076 LEAVE:
1077         g_variant_unref(result);
1078         g_object_unref(conn);
1079
1080         return ret;
1081 }
1082
1083 int _set_manual_route_info(unsigned int index, manual_route_info_s *info)
1084 {
1085         int ret = SOUND_MANAGER_ERROR_NONE;
1086         int i = 0;
1087         GVariantBuilder *builder_for_in_devices;
1088         GVariantBuilder *builder_for_out_devices;
1089         GVariant *result = NULL;
1090         GDBusConnection *conn = NULL;
1091         GError *err = NULL;
1092         const gchar *dbus_ret = NULL;
1093
1094         assert(info);
1095
1096         if ((ret = __get_dbus_connection(&conn)))
1097                 return SOUND_MANAGER_ERROR_INTERNAL;
1098
1099         LOGI("stream info index(%u)", index);
1100
1101         builder_for_in_devices = g_variant_builder_new(G_VARIANT_TYPE("au"));
1102         builder_for_out_devices = g_variant_builder_new(G_VARIANT_TYPE("au"));
1103         if (!builder_for_in_devices || !builder_for_out_devices) {
1104                 LOGE("failed to g_variant_builder_new(), builder_for_in_devices(%p), builder_for_out_devices(%p)",
1105                         builder_for_in_devices, builder_for_out_devices);
1106                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1107                 goto LEAVE;
1108         }
1109         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1110                 if (!info->route_in_devices[i])
1111                         break;
1112                 g_variant_builder_add(builder_for_in_devices, "u", info->route_in_devices[i]);
1113                 LOGI("[IN] device_id:%u", info->route_in_devices[i]);
1114         }
1115         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1116                 if (!info->route_out_devices[i])
1117                         break;
1118                 g_variant_builder_add(builder_for_out_devices, "u", info->route_out_devices[i]);
1119                 LOGI("[OUT] device_id:%u", info->route_out_devices[i]);
1120         }
1121
1122         result = g_dbus_connection_call_sync(conn,
1123                                                         PA_BUS_NAME,
1124                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1125                                                         PA_STREAM_MANAGER_INTERFACE,
1126                                                         PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES,
1127                                                         g_variant_new("(uauau)", index, builder_for_in_devices, builder_for_out_devices),
1128                                                         G_VARIANT_TYPE("(s)"),
1129                                                         G_DBUS_CALL_FLAGS_NONE,
1130                                                         DBUS_METHOD_TIMEOUT,
1131                                                         NULL,
1132                                                         &err);
1133         if (!result || err) {
1134                 //LCOV_EXCL_START
1135                 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_DEVICES error (%s)", err ? err->message : NULL);
1136                 if (err)
1137                         g_error_free(err);
1138                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1139                 goto LEAVE;
1140                 //LCOV_EXCL_STOP
1141         }
1142
1143         g_variant_get(result, "(&s)", &dbus_ret);
1144         LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1145         if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1146                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1147         else
1148                 info->is_set = true;
1149
1150 LEAVE:
1151         g_variant_unref(result);
1152         if (builder_for_in_devices)
1153                 g_variant_builder_unref(builder_for_in_devices);
1154         if (builder_for_out_devices)
1155                 g_variant_builder_unref(builder_for_out_devices);
1156         g_object_unref(conn);
1157
1158         return ret;
1159 }
1160
1161 //LCOV_EXCL_START
1162 int _set_route_option(unsigned int index, const char *name, int value)
1163 {
1164         int ret = SOUND_MANAGER_ERROR_NONE;
1165         GVariant *result = NULL;
1166         GDBusConnection *conn = NULL;
1167         GError *err = NULL;
1168         const gchar *dbus_ret = NULL;
1169
1170         assert(name);
1171
1172         if ((ret = __get_dbus_connection(&conn)))
1173                 return SOUND_MANAGER_ERROR_INTERNAL;
1174
1175         LOGI("[OPTION] %s(%d)", name, value);
1176
1177         result = g_dbus_connection_call_sync(conn,
1178                                                         PA_BUS_NAME,
1179                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1180                                                         PA_STREAM_MANAGER_INTERFACE,
1181                                                         PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION,
1182                                                         g_variant_new("(usi)", index, name, value),
1183                                                         G_VARIANT_TYPE("(s)"),
1184                                                         G_DBUS_CALL_FLAGS_NONE,
1185                                                         DBUS_METHOD_TIMEOUT,
1186                                                         NULL,
1187                                                         &err);
1188         if (!result || err) {
1189                 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_OPTION error (%s)", err ? err->message : NULL);
1190                 if (err)
1191                         g_error_free(err);
1192                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1193                 goto LEAVE;
1194         }
1195
1196         g_variant_get(result, "(&s)", &dbus_ret);
1197         LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1198         if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
1199                 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
1200         else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1201                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1202
1203 LEAVE:
1204         g_variant_unref(result);
1205         g_object_unref(conn);
1206
1207         return ret;
1208 }
1209 //LCOV_EXCL_STOP
1210
1211 int _get_volume_max_level(const char *direction, const char *volume_type, unsigned int *max_level)
1212 {
1213         int ret = SOUND_MANAGER_ERROR_NONE;
1214         GVariant *result = NULL;
1215         GDBusConnection *conn = NULL;
1216         GError *err = NULL;
1217         const gchar *dbus_ret = NULL;
1218
1219         assert(direction);
1220         assert(volume_type);
1221         assert(max_level);
1222
1223         if ((ret = __get_dbus_connection(&conn)))
1224                 return SOUND_MANAGER_ERROR_INTERNAL;
1225
1226         result = g_dbus_connection_call_sync(conn,
1227                                                         PA_BUS_NAME,
1228                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1229                                                         PA_STREAM_MANAGER_INTERFACE,
1230                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL,
1231                                                         g_variant_new("(ss)", direction, volume_type),
1232                                                         G_VARIANT_TYPE("(us)"),
1233                                                         G_DBUS_CALL_FLAGS_NONE,
1234                                                         DBUS_METHOD_TIMEOUT,
1235                                                         NULL,
1236                                                         &err);
1237         if (!result || err) {
1238                 //LCOV_EXCL_START
1239                 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_MAX_LEVEL error (%s)", err ? err->message : NULL);
1240                 if (err)
1241                         g_error_free(err);
1242                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1243                 goto LEAVE;
1244                 //LCOV_EXCL_STOP
1245         }
1246
1247         g_variant_get(result, "(u&s)", max_level, &dbus_ret);
1248         LOGI("g_dbus_connection_call_sync() success, method return value is (%u, %s)", *max_level, dbus_ret);
1249         if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1250                 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1251
1252 LEAVE:
1253         g_variant_unref(result);
1254         g_object_unref(conn);
1255
1256         return ret;
1257 }
1258
1259 //LCOV_EXCL_START
1260 int _get_volume_level(const char *direction, const char *volume_type, unsigned int *level)
1261 {
1262         int ret = SOUND_MANAGER_ERROR_NONE;
1263         GVariant *result = NULL;
1264         GDBusConnection *conn = NULL;
1265         GError *err = NULL;
1266         const gchar *dbus_ret = NULL;
1267
1268         assert(direction);
1269         assert(volume_type);
1270         assert(level);
1271
1272         if ((ret = __get_dbus_connection(&conn)))
1273                 return SOUND_MANAGER_ERROR_INTERNAL;
1274
1275         result = g_dbus_connection_call_sync(conn,
1276                                                         PA_BUS_NAME,
1277                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1278                                                         PA_STREAM_MANAGER_INTERFACE,
1279                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL,
1280                                                         g_variant_new("(ss)", direction, volume_type),
1281                                                         G_VARIANT_TYPE("(us)"),
1282                                                         G_DBUS_CALL_FLAGS_NONE,
1283                                                         DBUS_METHOD_TIMEOUT,
1284                                                         NULL,
1285                                                         &err);
1286         if (!result || err) {
1287                 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1288                 if (err)
1289                         g_error_free(err);
1290                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1291                 goto LEAVE;
1292         }
1293
1294         g_variant_get(result, "(u&s)", level, &dbus_ret);
1295         LOGI("g_dbus_connection_call_sync() success, method return value is (%u, %s)", *level, dbus_ret);
1296         if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1297                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1298
1299 LEAVE:
1300         g_variant_unref(result);
1301         g_object_unref(conn);
1302
1303         return ret;
1304 }
1305
1306 int _set_volume_level(const char *direction, const char *volume_type, unsigned int level)
1307 {
1308         int ret = SOUND_MANAGER_ERROR_NONE;
1309         GVariant *result = NULL;
1310         GDBusConnection *conn = NULL;
1311         GError *err = NULL;
1312         const gchar *dbus_ret = NULL;
1313         int vret = 0;
1314         char volume_path[VCONF_PATH_MAX] = {0,};
1315
1316         assert(direction);
1317         assert(volume_type);
1318
1319         if ((ret = __get_dbus_connection(&conn)))
1320                 return ret;
1321
1322         result = g_dbus_connection_call_sync(conn,
1323                                                         PA_BUS_NAME,
1324                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1325                                                         PA_STREAM_MANAGER_INTERFACE,
1326                                                         PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL,
1327                                                         g_variant_new("(ssu)", direction, volume_type, level),
1328                                                         G_VARIANT_TYPE("(s)"),
1329                                                         G_DBUS_CALL_FLAGS_NONE,
1330                                                         DBUS_METHOD_TIMEOUT,
1331                                                         NULL,
1332                                                         &err);
1333         if (!result || err) {
1334                 LOGE("g_dbus_connection_call_sync() for SET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1335                 if (err)
1336                         g_error_free(err);
1337                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1338                 goto LEAVE;
1339         }
1340
1341         g_variant_get(result, "(&s)", &dbus_ret);
1342         LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1343         if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1344                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1345         else {
1346                 /* Set volume value to VCONF */
1347                 snprintf(volume_path, sizeof(volume_path)-1, "%s%s", VCONF_PATH_PREFIX_VOLUME, volume_type);
1348                 if ((vret = vconf_set_int(volume_path, (int)level)))
1349                         LOGE("vconf_set_int(%s) failed..ret[%d]\n", volume_path, vret);
1350         }
1351
1352 LEAVE:
1353         g_variant_unref(result);
1354         g_object_unref(conn);
1355
1356         return ret;
1357 }
1358 //LCOV_EXCL_STOP
1359
1360 int _get_current_volume_type(const char *direction, char **volume_type)
1361 {
1362         int ret = SOUND_MANAGER_ERROR_NONE;
1363         GVariant *result = NULL;
1364         GDBusConnection *conn = NULL;
1365         GError *err = NULL;
1366         const gchar *dbus_volume_type = NULL;
1367         const gchar *dbus_ret = NULL;
1368
1369         assert(direction);
1370         assert(volume_type);
1371
1372         if ((ret = __get_dbus_connection(&conn)))
1373                 return SOUND_MANAGER_ERROR_INTERNAL;
1374
1375         result = g_dbus_connection_call_sync(conn,
1376                                                         PA_BUS_NAME,
1377                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1378                                                         PA_STREAM_MANAGER_INTERFACE,
1379                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE,
1380                                                         g_variant_new("(s)", direction),
1381                                                         G_VARIANT_TYPE("(ss)"),
1382                                                         G_DBUS_CALL_FLAGS_NONE,
1383                                                         DBUS_METHOD_TIMEOUT,
1384                                                         NULL,
1385                                                         &err);
1386         if (!result || err) {
1387                 //LCOV_EXCL_START
1388                 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_VOLUME_TYPE error (%s)", err ? err->message : NULL);
1389                 if (err)
1390                         g_error_free(err);
1391                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1392                 goto LEAVE;
1393                 //LCOV_EXCL_STOP
1394         }
1395
1396         g_variant_get(result, "(&s&s)", &dbus_volume_type, &dbus_ret);
1397         LOGI("g_dbus_connection_call_sync() success, method return value is (%s, %s)", dbus_volume_type, dbus_ret);
1398         if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
1399                 ret = SOUND_MANAGER_ERROR_NONE;//LCOV_EXCL_LINE
1400                 *volume_type = strdup(dbus_volume_type);//LCOV_EXCL_LINE
1401         } else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret))) {
1402                 ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
1403         } else {
1404                 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1405         }
1406
1407 LEAVE:
1408         g_variant_unref(result);
1409         g_object_unref(conn);
1410
1411         return ret;
1412 }
1413
1414 int _get_current_media_routing_path(const char *direction, sound_device_type_e *device_type)
1415 {
1416         int ret = SOUND_MANAGER_ERROR_NONE;
1417         GVariant *result = NULL;
1418         GDBusConnection *conn = NULL;
1419         GError *err = NULL;
1420         const gchar *dbus_device_type = NULL;
1421         const gchar *dbus_ret = NULL;
1422
1423         assert(direction);
1424         assert(device_type);
1425
1426         if ((ret = __get_dbus_connection(&conn)))
1427                 return SOUND_MANAGER_ERROR_INTERNAL;
1428
1429         result = g_dbus_connection_call_sync(conn,
1430                                                         PA_BUS_NAME,
1431                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1432                                                         PA_STREAM_MANAGER_INTERFACE,
1433                                                         PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH,
1434                                                         g_variant_new("(s)", direction),
1435                                                         G_VARIANT_TYPE("(ss)"),
1436                                                         G_DBUS_CALL_FLAGS_NONE,
1437                                                         DBUS_METHOD_TIMEOUT,
1438                                                         NULL,
1439                                                         &err);
1440         if (!result || err) {
1441                 //LCOV_EXCL_START
1442                 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_MEDIA_ROUTING_PATH error (%s)", err ? err->message : NULL);
1443                 if (err)
1444                         g_error_free(err);
1445                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1446                 goto LEAVE;
1447                 //LCOV_EXCL_STOP
1448         }
1449
1450         g_variant_get(result, "(&s&s)", &dbus_device_type, &dbus_ret);
1451         LOGI("g_dbus_connection_call_sync() success, method return value is (%s, %s)", dbus_device_type, dbus_ret);
1452         if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
1453                 if (_convert_device_type_str_to_enum(dbus_device_type, device_type) < 0)
1454                         ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1455         } else {
1456                 if (!strncmp("none", dbus_device_type, strlen(dbus_device_type)))
1457                         ret = SOUND_MANAGER_ERROR_NO_DATA;
1458                 else
1459                         ret = SOUND_MANAGER_ERROR_INTERNAL;
1460         }
1461
1462 LEAVE:
1463         g_variant_unref(result);
1464         g_object_unref(conn);
1465
1466         return ret;
1467 }
1468
1469 void _update_focus_status(unsigned int index, unsigned int acquired_focus_status)
1470 {
1471         GVariant *result = NULL;
1472         GDBusConnection *conn = NULL;
1473         GError *err = NULL;
1474         const gchar *dbus_ret = NULL;
1475
1476         if (__get_dbus_connection(&conn))
1477                 return;
1478
1479         result = g_dbus_connection_call_sync(conn,
1480                                                         PA_BUS_NAME,
1481                                                         PA_STREAM_MANAGER_OBJECT_PATH,
1482                                                         PA_STREAM_MANAGER_INTERFACE,
1483                                                         PA_STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS,
1484                                                         g_variant_new("(uu)", index, acquired_focus_status),
1485                                                         G_VARIANT_TYPE("(s)"),
1486                                                         G_DBUS_CALL_FLAGS_NONE,
1487                                                         DBUS_METHOD_TIMEOUT,
1488                                                         NULL,
1489                                                         &err);
1490         if (!result || err) {
1491                 //LCOV_EXCL_START
1492                 LOGE("g_dbus_connection_call_sync() for UPDATE_FOCUS_STATUS error (%s)", err ? err->message : NULL);
1493                 if (err)
1494                         g_error_free(err);
1495                 goto LEAVE;
1496                 //LCOV_EXCL_STOP
1497         }
1498         g_variant_get(result, "(&s)", &dbus_ret);
1499         LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1500         if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1501                 LOGE("failed to UPDATE_FOCUS_STATUS error (%s)", dbus_ret);//LCOV_EXCL_LINE
1502
1503 LEAVE:
1504         g_variant_unref(result);
1505         g_object_unref(conn);
1506
1507         return;
1508 }
1509
1510 //LCOV_EXCL_START
1511 int _is_device_running_by_id(int device_id, bool *is_running)
1512 {
1513         int ret = SOUND_MANAGER_ERROR_NONE;
1514         GVariant *result = NULL;
1515         GDBusConnection *conn = NULL;
1516         GError *err = NULL;
1517         gboolean _is_running;
1518
1519         assert(is_running);
1520
1521         if ((ret = __get_dbus_connection(&conn)))
1522                 return SOUND_MANAGER_ERROR_INTERNAL;
1523
1524         result = g_dbus_connection_call_sync(conn,
1525                                                                           PA_BUS_NAME,
1526                                                                           PA_DEVICE_MANAGER_OBJECT_PATH,
1527                                                                           PA_DEVICE_MANAGER_INTERFACE,
1528                                                                           PA_DEVICE_MANAGER_METHOD_NAME_IS_DEVICE_RUNNING_BY_ID,
1529                                                                           g_variant_new("(i)", device_id),
1530                                                                           G_VARIANT_TYPE("(b)"),
1531                                                                           G_DBUS_CALL_FLAGS_NONE,
1532                                                                           DBUS_METHOD_TIMEOUT,
1533                                                                           NULL,
1534                                                                           &err);
1535         if (err) {
1536                 LOGE("g_dbus_connection_call_sync() for IS_DEVICE_RUNNING_BY_ID error (%s)", err->message);
1537                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1538                 g_error_free(err);
1539                 goto LEAVE;
1540         } else {
1541                 g_variant_get(result, "(b)", &_is_running);
1542                 *is_running = (bool)_is_running;
1543                 LOGI("device(id:%d) is (%s)", device_id, *is_running ? "Running" : "Not running");
1544         }
1545
1546 LEAVE:
1547         g_variant_unref(result);
1548         g_object_unref(conn);
1549
1550         return ret;
1551 }
1552
1553 #define SM_SAMPLE_FORMAT_NUM    4 /* check declaration of sound_sample_format_e */
1554 int _get_supported_sample_formats(int device_id, sound_sample_format_e **formats, unsigned int *num)
1555 {
1556         int ret = SOUND_MANAGER_ERROR_NONE;
1557         GVariant *result = NULL;
1558         GDBusConnection *conn = NULL;
1559         GError *err = NULL;
1560         GVariantIter *iter = NULL;
1561         gchar *format_str;
1562         unsigned int iter_num;
1563         unsigned int elem_num = 0;
1564         sound_sample_format_e format;
1565         sound_sample_format_e sm_formats[SM_SAMPLE_FORMAT_NUM] = {0, };
1566
1567         SM_ARG_CHECK(formats);
1568         SM_ARG_CHECK(num);
1569
1570         if ((ret = __get_dbus_connection(&conn)))
1571                 return SOUND_MANAGER_ERROR_INTERNAL;
1572
1573         result = g_dbus_connection_call_sync(conn,
1574                                                         PA_BUS_NAME,
1575                                                         PA_DEVICE_MANAGER_OBJECT_PATH,
1576                                                         PA_DEVICE_MANAGER_INTERFACE,
1577                                                         PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_FORMATS,
1578                                                         g_variant_new("(i)", device_id),
1579                                                         G_VARIANT_TYPE("(as)"),
1580                                                         G_DBUS_CALL_FLAGS_NONE,
1581                                                         DBUS_METHOD_TIMEOUT,
1582                                                         NULL,
1583                                                         &err);
1584         if (!result || err) {
1585                 LOGE("g_dbus_connection_call_sync() for GET_SUPPORTED_SAMPLE_FORMATS error (%s)", err ? err->message : NULL);
1586                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1587                 if (err)
1588                         g_error_free(err);
1589                 goto LEAVE;
1590         }
1591
1592         g_variant_get(result, "(as)", &iter);
1593         if ((iter_num = (unsigned int) g_variant_iter_n_children(iter)) == 0) {
1594                 LOGE("could not get supported sample formats");
1595                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1596                 goto LEAVE;
1597         }
1598
1599         while (g_variant_iter_loop(iter, "&s", &format_str)) {
1600                 if (_convert_sample_format_str_to_enum((const char *)format_str, &format))
1601                         continue;
1602                 LOGI("%s(enum:%u) is supported", format_str, format);
1603                 elem_num++;
1604                 sm_formats[elem_num - 1] = format;
1605         }
1606
1607         if (elem_num == 0) {
1608                 LOGE("could not find supported sample formats");
1609                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1610                 goto LEAVE;
1611         }
1612
1613         if (!(*formats = (sound_sample_format_e *) calloc(elem_num, sizeof(sound_sample_format_e)))) {
1614                 LOGE("failed to calloc(), elem_num(%d)", elem_num);
1615                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1616                 goto LEAVE;
1617         } else {
1618                 memcpy(*formats, sm_formats, elem_num * sizeof(sound_sample_format_e));
1619         }
1620
1621         *num = elem_num;
1622
1623 LEAVE:
1624         g_variant_iter_free(iter);
1625         g_variant_unref(result);
1626         g_object_unref(conn);
1627
1628         return ret;
1629 }
1630
1631 int _set_sample_format(int device_id, sound_sample_format_e format)
1632 {
1633         int ret = SOUND_MANAGER_ERROR_NONE;
1634         GDBusConnection *conn = NULL;
1635         GError *err = NULL;
1636         char *format_str = NULL;
1637
1638         if ((ret = __get_dbus_connection(&conn)))
1639                 return SOUND_MANAGER_ERROR_INTERNAL;
1640
1641         if ((ret = _convert_sample_format_enum_to_str(format, &format_str)))
1642                 return ret;
1643
1644         g_dbus_connection_call_sync(conn,
1645                                                 PA_BUS_NAME,
1646                                                 PA_DEVICE_MANAGER_OBJECT_PATH,
1647                                                 PA_DEVICE_MANAGER_INTERFACE,
1648                                                 PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_FORMAT,
1649                                                 g_variant_new("(is)", device_id, format_str),
1650                                                 NULL,
1651                                                 G_DBUS_CALL_FLAGS_NONE,
1652                                                 DBUS_METHOD_TIMEOUT,
1653                                                 NULL,
1654                                                 &err);
1655         if (err) {
1656                 LOGE("g_dbus_connection_call_sync() for SET_SAMPLE_FORMAT error (%s)", err->message);
1657                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1658                 g_error_free(err);
1659         }
1660
1661         g_object_unref(conn);
1662
1663         return ret;
1664 }
1665
1666 int _get_sample_format(int device_id, sound_sample_format_e *format)
1667 {
1668         int ret = SOUND_MANAGER_ERROR_NONE;
1669         GVariant *result = NULL;
1670         GDBusConnection *conn = NULL;
1671         GError *err = NULL;
1672         gchar *format_str;
1673         sound_sample_format_e format_e;
1674
1675         SM_ARG_CHECK(format);
1676
1677         if ((ret = __get_dbus_connection(&conn)))
1678                 return SOUND_MANAGER_ERROR_INTERNAL;
1679
1680         result = g_dbus_connection_call_sync(conn,
1681                                                         PA_BUS_NAME,
1682                                                         PA_DEVICE_MANAGER_OBJECT_PATH,
1683                                                         PA_DEVICE_MANAGER_INTERFACE,
1684                                                         PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_FORMAT,
1685                                                         g_variant_new("(i)", device_id),
1686                                                         G_VARIANT_TYPE("(s)"),
1687                                                         G_DBUS_CALL_FLAGS_NONE,
1688                                                         DBUS_METHOD_TIMEOUT,
1689                                                         NULL,
1690                                                         &err);
1691         if (!result || err) {
1692                 LOGE("g_dbus_connection_call_sync() for GET_SAMPLE_FORMAT error (%s)", err ? err->message : NULL);
1693                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1694                 if (err)
1695                         g_error_free(err);
1696                 goto LEAVE;
1697         }
1698         g_variant_get(result, "(&s)", &format_str);
1699         if (!(ret = _convert_sample_format_str_to_enum((const char *)format_str, &format_e)))
1700                 *format = format_e;
1701
1702         g_variant_unref(result);
1703
1704 LEAVE:
1705         g_object_unref(conn);
1706
1707         return ret;
1708 }
1709
1710 #define SM_SAMPLE_RATE_NUM    8 /* check declaration of sound_sample_rate_e */
1711 int _get_supported_sample_rates(int device_id, sound_sample_rate_e **rates, unsigned int *num)
1712 {
1713         int ret = SOUND_MANAGER_ERROR_NONE;
1714         GVariant *result = NULL;
1715         GDBusConnection *conn = NULL;
1716         GError *err = NULL;
1717         GVariantIter *iter = NULL;
1718         unsigned int rate;
1719         unsigned int iter_num;
1720         unsigned int elem_num = 0;
1721         sound_sample_rate_e rate_e;
1722         sound_sample_rate_e sm_rates[SM_SAMPLE_RATE_NUM] = {0, };
1723
1724         SM_ARG_CHECK(rates);
1725         SM_ARG_CHECK(num);
1726
1727         if ((ret = __get_dbus_connection(&conn)))
1728                 return SOUND_MANAGER_ERROR_INTERNAL;
1729
1730         result = g_dbus_connection_call_sync(conn,
1731                                                         PA_BUS_NAME,
1732                                                         PA_DEVICE_MANAGER_OBJECT_PATH,
1733                                                         PA_DEVICE_MANAGER_INTERFACE,
1734                                                         PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_RATES,
1735                                                         g_variant_new("(i)", device_id),
1736                                                         G_VARIANT_TYPE("(au)"),
1737                                                         G_DBUS_CALL_FLAGS_NONE,
1738                                                         DBUS_METHOD_TIMEOUT,
1739                                                         NULL,
1740                                                         &err);
1741         if (!result || err) {
1742                 LOGE("g_dbus_connection_call_sync() for GET_SUPPORTED_SAMPLE_RATES error (%s)", err ? err->message : NULL);
1743                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1744                 if (err)
1745                         g_error_free(err);
1746                 goto LEAVE;
1747         }
1748
1749         g_variant_get(result, "(au)", &iter);
1750         if ((iter_num = (unsigned int) g_variant_iter_n_children(iter)) == 0) {
1751                 LOGE("could not get supported sample rates");
1752                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1753                 goto LEAVE;
1754         }
1755
1756         while (g_variant_iter_loop(iter, "u", &rate)) {
1757                 if (_convert_sample_rate_to_enum(rate, &rate_e))
1758                         continue;
1759                 LOGI("%u(enum:%u) is supported", rate, rate_e);
1760                 elem_num++;
1761                 sm_rates[elem_num - 1] = rate_e;
1762         }
1763
1764         if (elem_num == 0) {
1765                 LOGE("could not find supported sample rates");
1766                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1767                 goto LEAVE;
1768         }
1769
1770         if (!(*rates = (sound_sample_rate_e *) calloc(elem_num, sizeof(sound_sample_rate_e)))) {
1771                 LOGE("failed to calloc(), elem_num(%d)", elem_num);
1772                 ret = SOUND_MANAGER_ERROR_INTERNAL;
1773                 goto LEAVE;
1774         } else {
1775                 memcpy(*rates, sm_rates, elem_num * sizeof(sound_sample_rate_e));
1776         }
1777
1778         *num = elem_num;
1779
1780 LEAVE:
1781         g_variant_iter_free(iter);
1782         g_variant_unref(result);
1783         g_object_unref(conn);
1784
1785         return ret;
1786 }
1787
1788 int _set_sample_rate(int device_id, sound_sample_rate_e rate)
1789 {
1790         int ret = SOUND_MANAGER_ERROR_NONE;
1791         GDBusConnection *conn = NULL;
1792         GError *err = NULL;
1793         unsigned int _rate;
1794
1795         if ((ret = __get_dbus_connection(&conn)))
1796                 return SOUND_MANAGER_ERROR_INTERNAL;
1797
1798         if ((ret = _convert_sample_rate_enum_to_uint(rate, &_rate)))
1799                 return ret;
1800
1801         g_dbus_connection_call_sync(conn,
1802                                                 PA_BUS_NAME,
1803                                                 PA_DEVICE_MANAGER_OBJECT_PATH,
1804                                                 PA_DEVICE_MANAGER_INTERFACE,
1805                                                 PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_RATE,
1806                                                 g_variant_new("(iu)", device_id, _rate),
1807                                                 NULL,
1808                                                 G_DBUS_CALL_FLAGS_NONE,
1809                                                 DBUS_METHOD_TIMEOUT,
1810                                                 NULL,
1811                                                 &err);
1812         if (err) {
1813                 LOGE("g_dbus_connection_call_sync() for SET_SAMPLE_RATE error (%s)", err->message);
1814                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1815                 g_error_free(err);
1816         }
1817
1818         g_object_unref(conn);
1819
1820         return ret;
1821 }
1822
1823 int _get_sample_rate(int device_id, sound_sample_rate_e *rate)
1824 {
1825         int ret = SOUND_MANAGER_ERROR_NONE;
1826         GVariant *result = NULL;
1827         GDBusConnection *conn = NULL;
1828         GError *err = NULL;
1829         unsigned int _rate;
1830         sound_sample_rate_e rate_e;
1831
1832         SM_NULL_ARG_CHECK_FOR_PRIV(rate);
1833
1834         if ((ret = __get_dbus_connection(&conn)))
1835                 return SOUND_MANAGER_ERROR_INTERNAL;
1836
1837         result = g_dbus_connection_call_sync(conn,
1838                                                         PA_BUS_NAME,
1839                                                         PA_DEVICE_MANAGER_OBJECT_PATH,
1840                                                         PA_DEVICE_MANAGER_INTERFACE,
1841                                                         PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_RATE,
1842                                                         g_variant_new("(i)", device_id),
1843                                                         G_VARIANT_TYPE("(u)"),
1844                                                         G_DBUS_CALL_FLAGS_NONE,
1845                                                         DBUS_METHOD_TIMEOUT,
1846                                                         NULL,
1847                                                         &err);
1848         if (!result || err) {
1849                 LOGE("g_dbus_connection_call_sync() for GET_SAMPLE_RATE error (%s)", err ? err->message : NULL);
1850                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1851                 if (err)
1852                         g_error_free(err);
1853                 goto LEAVE;
1854         }
1855         g_variant_get(result, "(u)", &_rate);
1856         if (!(ret = _convert_sample_rate_to_enum(_rate, &rate_e)))
1857                 *rate = rate_e;
1858
1859         g_variant_unref(result);
1860
1861 LEAVE:
1862         g_object_unref(conn);
1863
1864         return ret;
1865 }
1866
1867 int _set_avoid_resampling(int device_id, bool enable)
1868 {
1869         int ret = SOUND_MANAGER_ERROR_NONE;
1870         GDBusConnection *conn = NULL;
1871         GError *err = NULL;
1872
1873         if ((ret = __get_dbus_connection(&conn)))
1874                 return SOUND_MANAGER_ERROR_INTERNAL;
1875
1876         g_dbus_connection_call_sync(conn,
1877                                                 PA_BUS_NAME,
1878                                                 PA_DEVICE_MANAGER_OBJECT_PATH,
1879                                                 PA_DEVICE_MANAGER_INTERFACE,
1880                                                 PA_DEVICE_MANAGER_METHOD_NAME_SET_AVOID_RESAMPLING,
1881                                                 g_variant_new("(ib)", device_id, enable),
1882                                                 NULL,
1883                                                 G_DBUS_CALL_FLAGS_NONE,
1884                                                 DBUS_METHOD_TIMEOUT,
1885                                                 NULL,
1886                                                 &err);
1887         if (err) {
1888                 LOGE("g_dbus_connection_call_sync() for SET_AVOID_RESAMPLING error (%s)", err->message);
1889                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1890                 g_error_free(err);
1891         }
1892
1893         g_object_unref(conn);
1894
1895         return ret;
1896 }
1897
1898 int _get_avoid_resampling(int device_id, bool *enabled)
1899 {
1900         int ret = SOUND_MANAGER_ERROR_NONE;
1901         GVariant *result = NULL;
1902         GDBusConnection *conn = NULL;
1903         GError *err = NULL;
1904         gboolean _enabled;
1905
1906         SM_NULL_ARG_CHECK_FOR_PRIV(enabled);
1907
1908         if ((ret = __get_dbus_connection(&conn)))
1909                 return SOUND_MANAGER_ERROR_INTERNAL;
1910
1911         result = g_dbus_connection_call_sync(conn,
1912                                                         PA_BUS_NAME,
1913                                                         PA_DEVICE_MANAGER_OBJECT_PATH,
1914                                                         PA_DEVICE_MANAGER_INTERFACE,
1915                                                         PA_DEVICE_MANAGER_METHOD_NAME_GET_AVOID_RESAMPLING,
1916                                                         g_variant_new("(i)", device_id),
1917                                                         G_VARIANT_TYPE("(b)"),
1918                                                         G_DBUS_CALL_FLAGS_NONE,
1919                                                         DBUS_METHOD_TIMEOUT,
1920                                                         NULL,
1921                                                         &err);
1922         if (!result || err) {
1923                 LOGE("g_dbus_connection_call_sync() for GET_AVOID_RESAMPLING error (%s)", err ? err->message : NULL);
1924                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1925                 if (err)
1926                         g_error_free(err);
1927                 goto LEAVE;
1928         }
1929
1930         g_variant_get(result, "(b)", &_enabled);
1931         *enabled = (bool)_enabled;
1932         g_variant_unref(result);
1933
1934 LEAVE:
1935         g_object_unref(conn);
1936
1937         return ret;
1938 }
1939
1940 int _set_media_stream_only(int device_id, bool enable)
1941 {
1942         int ret = SOUND_MANAGER_ERROR_NONE;
1943         GDBusConnection *conn = NULL;
1944         GError *err = NULL;
1945         const char *stream_type;
1946
1947         if ((ret = __get_dbus_connection(&conn)))
1948                 return SOUND_MANAGER_ERROR_INTERNAL;
1949
1950         if (enable)
1951                 stream_type = STREAM_MEDIA;
1952         else
1953                 stream_type = "none";
1954
1955         g_dbus_connection_call_sync(conn,
1956                                                 PA_BUS_NAME,
1957                                                 PA_DEVICE_MANAGER_OBJECT_PATH,
1958                                                 PA_DEVICE_MANAGER_INTERFACE,
1959                                                 PA_DEVICE_MANAGER_METHOD_NAME_SET_SPECIFIC_STREAM,
1960                                                 g_variant_new("(is)", device_id, stream_type),
1961                                                 NULL,
1962                                                 G_DBUS_CALL_FLAGS_NONE,
1963                                                 DBUS_METHOD_TIMEOUT,
1964                                                 NULL,
1965                                                 &err);
1966         if (err) {
1967                 LOGE("g_dbus_connection_call_sync() for SET_SPECIFIC_STREAM error (%s)", err->message);
1968                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1969                 g_error_free(err);
1970         }
1971
1972         g_object_unref(conn);
1973
1974         return ret;
1975 }
1976
1977 int _get_media_stream_only(int device_id, bool *enabled)
1978 {
1979         int ret = SOUND_MANAGER_ERROR_NONE;
1980         GVariant *result = NULL;
1981         GDBusConnection *conn = NULL;
1982         GError *err = NULL;
1983         char *stream_type;
1984
1985         SM_NULL_ARG_CHECK_FOR_PRIV(enabled);
1986
1987         if ((ret = __get_dbus_connection(&conn)))
1988                 return SOUND_MANAGER_ERROR_INTERNAL;
1989
1990         result = g_dbus_connection_call_sync(conn,
1991                                                         PA_BUS_NAME,
1992                                                         PA_DEVICE_MANAGER_OBJECT_PATH,
1993                                                         PA_DEVICE_MANAGER_INTERFACE,
1994                                                         PA_DEVICE_MANAGER_METHOD_NAME_GET_SPECIFIED_STREAM,
1995                                                         g_variant_new("(i)", device_id),
1996                                                         G_VARIANT_TYPE("(s)"),
1997                                                         G_DBUS_CALL_FLAGS_NONE,
1998                                                         DBUS_METHOD_TIMEOUT,
1999                                                         NULL,
2000                                                         &err);
2001         if (!result || err) {
2002                 LOGE("g_dbus_connection_call_sync() for GET_SPECIFIED_STREAM error (%s)", err ? err->message : NULL);
2003                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
2004                 if (err)
2005                         g_error_free(err);
2006                 goto LEAVE;
2007         }
2008
2009         g_variant_get(result, "(&s)", &stream_type);
2010         if (!strncmp(stream_type, STREAM_MEDIA, SOUND_STREAM_TYPE_LEN))
2011                 *enabled = true;
2012         else
2013                 *enabled = false;
2014
2015         g_variant_unref(result);
2016
2017 LEAVE:
2018         g_object_unref(conn);
2019
2020         return ret;
2021 }
2022 //LCOV_EXCL_STOP
2023
2024 int _make_pa_connection(sound_pa_info_s *pa_info, const char *context_name)
2025 {
2026         int pa_ret = PA_OK;
2027
2028         SM_ARG_CHECK(pa_info);
2029
2030         if (!(pa_info->mainloop = pa_threaded_mainloop_new()))
2031                 goto PA_ERROR;
2032
2033         if (!(pa_info->context = pa_context_new(pa_threaded_mainloop_get_api(pa_info->mainloop), context_name)))
2034                 goto PA_ERROR;
2035
2036         pa_context_set_state_callback(pa_info->context, _pa_context_state_cb, pa_info);
2037
2038         if (pa_context_connect(pa_info->context, NULL, 0, NULL) < 0) {
2039                 pa_ret = pa_context_errno(pa_info->context);//LCOV_EXCL_LINE
2040                 goto PA_ERROR;
2041         }
2042
2043         pa_threaded_mainloop_lock(pa_info->mainloop);
2044
2045         if (pa_threaded_mainloop_start(pa_info->mainloop) < 0)
2046                 goto PA_ERROR_WITH_UNLOCK;
2047
2048         /* wait for ready state of the context */
2049         for (;;) {
2050                 pa_context_state_t state;
2051                 state = pa_context_get_state(pa_info->context);
2052                 if (state == PA_CONTEXT_READY)
2053                         break;
2054                 if (!PA_CONTEXT_IS_GOOD(state)) {
2055                         pa_ret = pa_context_errno(pa_info->context);//LCOV_EXCL_LINE
2056                         goto PA_ERROR_WITH_UNLOCK;
2057                 }
2058                 pa_threaded_mainloop_wait(pa_info->mainloop);
2059         }
2060
2061         /* get index of this context */
2062         pa_info->index = pa_context_get_index(pa_info->context);
2063
2064         pa_threaded_mainloop_unlock(pa_info->mainloop);
2065
2066         return SOUND_MANAGER_ERROR_NONE;
2067 //LCOV_EXCL_START
2068 PA_ERROR_WITH_UNLOCK:
2069         pa_threaded_mainloop_unlock(pa_info->mainloop);
2070
2071 PA_ERROR:
2072         _destroy_pa_connection(pa_info);
2073         LOGE("pa_ret %d", pa_ret);
2074
2075         return SOUND_MANAGER_ERROR_INTERNAL;
2076 //LCOV_EXCL_STOP
2077 }
2078
2079 int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_stream_focus_state_changed_cb callback, void *user_data)
2080 {
2081         int ret = SOUND_MANAGER_ERROR_NONE;
2082         int mm_ret = MM_ERROR_NONE;
2083         int i = 0;
2084         bool is_focus_cb_thread = false;
2085
2086         if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
2087                 return _convert_sound_manager_error_code(__func__, mm_ret);
2088
2089         if (is_focus_cb_thread)
2090                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2091
2092         /* get configuration information of this stream type */
2093         if ((ret = _get_stream_conf_info(stream_h->stream_type, &stream_h->stream_conf_info)))
2094                 return ret;
2095
2096         LOGI("stream_conf_info : stream type[%s], priority[%d], route type[%d]",
2097                 stream_h->stream_type, stream_h->stream_conf_info.priority, stream_h->stream_conf_info.route_type);
2098
2099         if ((ret = _make_pa_connection(&stream_h->pa_info, "SOUND_MANAGER_STREAM_INFO")))
2100                 goto ERROR;
2101
2102         /* register focus */
2103         if (!stream_h->is_focus_unavailable) {
2104                 mm_ret = mm_sound_register_focus(stream_h->stream_type, _focus_state_change_callback, stream_h, &stream_h->focus_id);
2105                 if (mm_ret == MM_ERROR_NONE) {
2106                         stream_h->user_cb = callback;
2107                         stream_h->user_data = user_data;
2108                 } else {
2109                         LOGE("failed to register focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2110                         ret = _convert_sound_manager_error_code(__func__, mm_ret);
2111                         goto ERROR;
2112                 }
2113         }
2114         goto SUCCESS;
2115 //LCOV_EXCL_START
2116 ERROR:
2117         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2118                 SM_SAFE_FREE(stream_h->stream_conf_info.avail_in_devices[i]);
2119                 SM_SAFE_FREE(stream_h->stream_conf_info.avail_out_devices[i]);
2120         }
2121         for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2122                 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2123
2124         SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2125
2126         _destroy_pa_connection(&stream_h->pa_info);
2127 //LCOV_EXCL_STOP
2128 SUCCESS:
2129         return ret;
2130 }
2131
2132 void _destroy_pa_connection(sound_pa_info_s *pa_info)
2133 {
2134         if (!pa_info) {
2135                 LOGW("NULL pa info - skip..");
2136                 return;
2137         }
2138
2139         LOGI("[%p][%p]", pa_info->mainloop, pa_info->context);
2140
2141         if (pa_info->mainloop)
2142                 pa_threaded_mainloop_stop(pa_info->mainloop);
2143
2144         if (pa_info->context) {
2145                 pa_context_disconnect(pa_info->context);
2146                 pa_context_unref(pa_info->context);
2147                 pa_info->context = NULL;
2148         }
2149
2150         if (pa_info->mainloop) {
2151                 pa_threaded_mainloop_free(pa_info->mainloop);
2152                 pa_info->mainloop = NULL;
2153         }
2154
2155         return;
2156 }
2157
2158 int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h)
2159 {
2160         int i = 0;
2161         int ret = SOUND_MANAGER_ERROR_NONE;
2162         int mm_ret = MM_ERROR_NONE;
2163         bool is_focus_cb_thread = false;
2164
2165         if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
2166                 return _convert_sound_manager_error_code(__func__, mm_ret);
2167
2168         if (is_focus_cb_thread)
2169                 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2170
2171         _destroy_pa_connection(&stream_h->pa_info);
2172
2173         /* unregister focus */
2174         if (!stream_h->is_focus_unavailable) {
2175                 mm_ret = mm_sound_unregister_focus(stream_h->focus_id);
2176                 if (mm_ret) {
2177                         LOGE("failed to unregister focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2178                         ret = _convert_sound_manager_error_code(__func__, mm_ret);
2179                 }
2180         }
2181
2182         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2183                 SM_SAFE_FREE(stream_h->stream_conf_info.avail_in_devices[i]);
2184                 SM_SAFE_FREE(stream_h->stream_conf_info.avail_out_devices[i]);
2185         }
2186         for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2187                 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2188
2189         SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2190
2191         return ret;
2192 }
2193
2194 static int __check_manual_route_type(sound_stream_info_s *stream_info)
2195 {
2196         SM_ARG_CHECK(stream_info);
2197
2198         if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL &&
2199                 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL_EXT) {
2200                 LOGE("route type is not manual or manual-ext");
2201                 return SOUND_MANAGER_ERROR_POLICY;
2202         }
2203
2204         return SOUND_MANAGER_ERROR_NONE;
2205 }
2206
2207 static int __check_auto_route_type(sound_stream_info_s *stream_info)
2208 {
2209         SM_ARG_CHECK(stream_info);
2210
2211         if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO &&
2212                 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
2213                 LOGE("route type is not auto or auto-last-connected");
2214                 return SOUND_MANAGER_ERROR_INTERNAL;
2215         }
2216
2217         return SOUND_MANAGER_ERROR_NONE;
2218 }
2219
2220 static int __add_device_to_stream_info(sound_stream_info_s *stream_info, int device_id, mm_sound_device_io_direction_e device_direction, char *device_type_str)
2221 {
2222         int i, j;
2223         bool added_successfully = false;
2224
2225         SM_ARG_CHECK(stream_info);
2226         SM_ARG_CHECK(device_type_str);
2227
2228         if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2229                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2230                         if (!stream_info->stream_conf_info.avail_in_devices[i])
2231                                 break;
2232                         if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2233                                 continue;
2234
2235                         for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2236                                 if (!stream_info->manual_route_info.route_in_devices[j]) {
2237                                         stream_info->manual_route_info.route_in_devices[j] = (unsigned int)device_id;
2238                                         added_successfully = true;
2239                                         break;
2240                                 }
2241                                 if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
2242                                         LOGE("failed to add device, this IN/BOTH-device[type:%s, id:%d] has been already set", device_type_str, device_id);
2243                                         return SOUND_MANAGER_ERROR_POLICY;
2244                                 }
2245                         }
2246                 }
2247         }
2248         if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2249                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2250                         if (!stream_info->stream_conf_info.avail_out_devices[i])
2251                                 break;
2252                         if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2253                                 continue;
2254
2255                         for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2256                                 if (!stream_info->manual_route_info.route_out_devices[j]) {
2257                                         stream_info->manual_route_info.route_out_devices[j] = (unsigned int)device_id;
2258                                         added_successfully = true;
2259                                         break;
2260                                 }
2261                                 if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
2262                                         LOGE("failed to add device, this OUT/BOTH-device[type:%s, id:%d] has been already set", device_type_str, device_id);
2263                                         return SOUND_MANAGER_ERROR_POLICY;
2264                                 }
2265                         }
2266                 }
2267         }
2268
2269         if (!added_successfully) {
2270                 LOGE("failed to add device, not supported device[type:%s, id:%d]", device_type_str, device_id);
2271                 return SOUND_MANAGER_ERROR_POLICY;
2272         }
2273
2274         return SOUND_MANAGER_ERROR_NONE;
2275 }
2276
2277 static int __remove_device_from_stream_info(sound_stream_info_s *stream_info, int device_id, mm_sound_device_io_direction_e device_direction, char *device_type_str)
2278 {
2279         int i, j;
2280         bool removed_successfully = false;
2281
2282         SM_ARG_CHECK(stream_info);
2283         SM_ARG_CHECK(device_type_str);
2284
2285         if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2286                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2287                         if (!stream_info->stream_conf_info.avail_in_devices[i])
2288                                 break;
2289                         if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2290                                 continue;
2291
2292                         for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2293                                 if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
2294                                         removed_successfully = true;
2295                                         stream_info->manual_route_info.route_in_devices[j] = 0;
2296                                         break;
2297                                 }
2298                         }
2299                 }
2300         }
2301         if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2302                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2303                         if (!stream_info->stream_conf_info.avail_out_devices[i])
2304                                 break;
2305                         if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2306                                 continue;
2307
2308                         for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2309                                 if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
2310                                         removed_successfully = true;
2311                                         stream_info->manual_route_info.route_out_devices[j] = 0;
2312                                         break;
2313                                 }
2314                         }
2315                 }
2316         }
2317
2318         if (!removed_successfully) {
2319                 LOGE("failed to remove device, could not find this device[type:%s, id:%d]", device_type_str, device_id);
2320                 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
2321         }
2322
2323         return SOUND_MANAGER_ERROR_NONE;
2324 }
2325
2326 static int __is_available_device(sound_stream_info_s *stream_info, sound_device_h device, bool *available)
2327 {
2328         int ret = SOUND_MANAGER_ERROR_NONE;
2329         int mm_ret = MM_ERROR_NONE;
2330         int i = 0;
2331         mm_sound_device_type_e mm_sound_device_type;
2332         sound_device_type_e device_type;
2333         char *device_type_str = NULL;
2334         char *avail_device_item = NULL;
2335         mm_sound_device_io_direction_e device_direction;
2336         bool found = false;
2337
2338         SM_ARG_CHECK(stream_info);
2339         SM_ARG_CHECK(device);
2340
2341         if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)))
2342                 return _convert_sound_manager_error_code(__func__, mm_ret);
2343         if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2344                 return ret;
2345         if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2346                 return ret;
2347         if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)))
2348                 return _convert_sound_manager_error_code(__func__, mm_ret);
2349
2350         if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_OUT) {
2351                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2352                         if (!(avail_device_item = stream_info->stream_conf_info.avail_out_devices[i]))
2353                                 break;
2354                         if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2355                                 found = true;
2356                 }
2357                 if (!found) {
2358                         LOGE("[OUT] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2359                         *available = false;
2360                         return ret;
2361                 }
2362         }
2363
2364         if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_IN) {
2365                 found = false;
2366                 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2367                         if (!(avail_device_item = stream_info->stream_conf_info.avail_in_devices[i]))
2368                                 break;
2369                         if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2370                                 found = true;
2371                 }
2372                 if (!found) {
2373                         LOGE("[IN] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2374                         *available = false;
2375                         return ret;
2376                 }
2377         }
2378
2379         *available = true;
2380
2381         return ret;
2382 }
2383
2384 int _add_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2385 {
2386         int ret = SOUND_MANAGER_ERROR_NONE;
2387         int mm_ret = MM_ERROR_NONE;
2388         char *device_type_str = NULL;
2389         int device_id = 0;
2390         mm_sound_device_type_e mm_sound_device_type;
2391         mm_sound_device_io_direction_e device_direction;
2392         sound_device_type_e device_type;
2393
2394         SM_ARG_CHECK(stream_info);
2395         SM_ARG_CHECK(device);
2396
2397         if ((ret = __check_manual_route_type(stream_info)))
2398                 return ret;
2399
2400         if ((mm_ret = mm_sound_get_device_id(device, &device_id)))
2401                 return _convert_sound_manager_error_code(__func__, mm_ret);
2402         if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)))
2403                 return _convert_sound_manager_error_code(__func__, mm_ret);
2404         if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2405                 return ret;
2406         if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2407                 return ret;
2408         if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)))
2409                 return _convert_sound_manager_error_code(__func__, mm_ret);
2410
2411         if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)))
2412                 return ret;
2413
2414         LOGI("*** added device[type:%s, id:%d]", device_type_str, device_id);
2415
2416         return ret;
2417 }
2418
2419 int _remove_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2420 {
2421         int ret = SOUND_MANAGER_ERROR_NONE;
2422         int mm_ret = MM_ERROR_NONE;
2423         char *device_type_str = NULL;
2424         int device_id = 0;
2425         mm_sound_device_type_e mm_sound_device_type;
2426         mm_sound_device_io_direction_e device_direction;
2427         sound_device_type_e device_type;
2428
2429         SM_ARG_CHECK(stream_info);
2430         SM_ARG_CHECK(device);
2431
2432         if ((ret = __check_manual_route_type(stream_info)))
2433                 return ret;
2434
2435         if ((mm_ret = mm_sound_get_device_id(device, &device_id)))
2436                 return _convert_sound_manager_error_code(__func__, mm_ret);
2437         if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)))
2438                 return _convert_sound_manager_error_code(__func__, mm_ret);
2439         if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2440                 return ret;
2441         if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2442                 return ret;
2443         if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)))
2444                 return _convert_sound_manager_error_code(__func__, mm_ret);
2445
2446         if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)))
2447                 return ret;
2448
2449         LOGI("*** removed device[type:%s, id:%d]", device_type_str, device_id);
2450
2451         return ret;
2452 }
2453
2454 int _remove_all_devices_for_stream_routing(sound_stream_info_s *stream_info)
2455 {
2456         int ret = SOUND_MANAGER_ERROR_NONE;
2457         int i;
2458
2459         SM_ARG_CHECK(stream_info);
2460
2461         if ((ret = __check_manual_route_type(stream_info)))
2462                 return ret;
2463
2464         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2465                 stream_info->manual_route_info.route_in_devices[i] = 0;
2466                 stream_info->manual_route_info.route_out_devices[i] = 0;
2467         }
2468
2469         stream_info->manual_route_info.is_set = false;
2470
2471         LOGI("*** removed all devices");
2472
2473         return ret;
2474 }
2475 //LCOV_EXCL_START
2476 int _add_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
2477 {
2478         int ret = SOUND_MANAGER_ERROR_NONE;
2479         int mm_ret = MM_ERROR_NONE;
2480         char *device_type_str = NULL;
2481         mm_sound_device_type_e mm_sound_device_type;
2482         mm_sound_device_io_direction_e device_direction;
2483         sound_device_type_e device_type;
2484         MMSoundDevice_t device = NULL;
2485
2486         SM_ARG_CHECK(stream_info);
2487
2488         if ((ret = __check_manual_route_type(stream_info)))
2489                 return ret;
2490
2491         if ((mm_ret = mm_sound_get_device_by_id(device_id, &device)))
2492                 return _convert_sound_manager_error_code(__func__, mm_ret);
2493         if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type))) {
2494                 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2495                 goto LEAVE;
2496         }
2497         if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2498                 goto LEAVE;
2499         if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2500                 goto LEAVE;
2501         if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction))) {
2502                 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2503                 goto LEAVE;
2504         }
2505
2506         if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)))
2507                 goto LEAVE;
2508
2509         LOGI("*** added device by id[type:%s, id:%d]", device_type_str, device_id);
2510
2511 LEAVE:
2512         if (device)
2513                 mm_sound_free_device(device);
2514         return ret;
2515 }
2516
2517 int _remove_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
2518 {
2519         int ret = SOUND_MANAGER_ERROR_NONE;
2520         int mm_ret = MM_ERROR_NONE;
2521         char *device_type_str = NULL;
2522         mm_sound_device_type_e mm_sound_device_type;
2523         mm_sound_device_io_direction_e device_direction;
2524         sound_device_type_e device_type;
2525         MMSoundDevice_t device = NULL;
2526
2527         SM_ARG_CHECK(stream_info);
2528
2529         if ((ret = __check_manual_route_type(stream_info)))
2530                 return ret;
2531
2532         if ((mm_ret = mm_sound_get_device_by_id(device_id, &device)))
2533                 return _convert_sound_manager_error_code(__func__, mm_ret);
2534         if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type))) {
2535                 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2536                 goto LEAVE;
2537         }
2538         if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2539                 goto LEAVE;
2540         if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2541                 goto LEAVE;
2542         if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction))) {
2543                 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2544                 goto LEAVE;
2545         }
2546
2547         if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)))
2548                 goto LEAVE;
2549
2550         LOGI("*** removed device by id[type:%s, id:%d]", device_type_str, device_id);
2551
2552 LEAVE:
2553         if (device)
2554                 mm_sound_free_device(device);
2555         return ret;
2556 }
2557 //LCOV_EXCL_STOP
2558 int _apply_stream_routing(sound_stream_info_s *stream_info)
2559 {
2560         int i = 0;
2561
2562         SM_ARG_CHECK(stream_info);
2563
2564         if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL &&
2565                 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL_EXT) {
2566                 LOGE("route type is not manual or manual-ext");//LCOV_EXCL_LINE
2567                 /* Differ from others, it uses SOUND_INTERNAL error.
2568                  * ACR process is required prior to changing error value. */
2569                 return SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
2570         }
2571
2572         for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2573                 if (stream_info->manual_route_info.route_in_devices[i] ||
2574                     stream_info->manual_route_info.route_out_devices[i])
2575                         return _set_manual_route_info(stream_info->pa_info.index, &stream_info->manual_route_info);
2576         }
2577
2578         return SOUND_MANAGER_ERROR_INVALID_STATE;
2579 }
2580
2581 //LCOV_EXCL_START
2582 int _create_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream)
2583 {
2584         int ret = MM_ERROR_NONE;
2585         bool result = false;
2586         const char *name = NULL;
2587         int i = 0;
2588
2589         SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2590         SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
2591
2592         /* check if this stream_info is available for virtual stream */
2593         name = _convert_api_name(NATIVE_API_SOUND_MANAGER);
2594         for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++) {
2595                 if (stream_info->stream_conf_info.avail_frameworks[i] && !strncmp(stream_info->stream_conf_info.avail_frameworks[i], name, strlen(name))) {
2596                         result = true;
2597                         break;
2598                 }
2599         }
2600         LOGI("stream_type[%s], native api[%s], is_available[%d]", stream_info->stream_type, name, result);
2601         if (result == false) {
2602                 ret = MM_ERROR_NOT_SUPPORT_API;
2603                 goto LEAVE;
2604         }
2605
2606         (*virtual_stream) = malloc(sizeof(virtual_sound_stream_info_s));
2607         if (!(*virtual_stream)) {
2608                 ret = MM_ERROR_OUT_OF_MEMORY;
2609                 goto LEAVE;
2610         }
2611
2612         memset((*virtual_stream), 0, sizeof(virtual_sound_stream_info_s));
2613         (*virtual_stream)->stream_type = stream_info->stream_type;
2614         (*virtual_stream)->pa_mainloop = stream_info->pa_info.mainloop;
2615         (*virtual_stream)->pa_context = stream_info->pa_info.context;
2616         (*virtual_stream)->pa_proplist = pa_proplist_new();
2617         pa_proplist_sets((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_ROLE, (*virtual_stream)->stream_type);
2618         pa_proplist_setf((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_PARENT_ID, "%u", stream_info->pa_info.index);
2619         (*virtual_stream)->state = _VSTREAM_STATE_READY;
2620         (*virtual_stream)->stream_info = stream_info;
2621
2622 LEAVE:
2623         return ret;
2624 }
2625
2626 int _destroy_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2627 {
2628         int ret = MM_ERROR_NONE;
2629
2630         SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2631         SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_READY);
2632
2633         virtual_stream->pa_mainloop = NULL;
2634         virtual_stream->pa_context = NULL;
2635         if (virtual_stream->pa_proplist)
2636                 pa_proplist_free(virtual_stream->pa_proplist);
2637
2638         SM_SAFE_FREE(virtual_stream);
2639
2640         return ret;
2641 }
2642
2643 int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2644 {
2645         int ret = MM_ERROR_NONE;
2646         int pa_ret = PA_OK;
2647         int i = 0;
2648         int io_direction = 0;
2649         pa_sample_spec ss;
2650         pa_channel_map maps;
2651
2652         SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2653         SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_READY);
2654
2655         /* fill up with default value */
2656         ss.channels = 2;
2657         ss.rate = 44100;
2658         ss.format = PA_SAMPLE_S16LE;
2659         pa_channel_map_init_auto(&maps, ss.channels, PA_CHANNEL_MAP_ALSA);
2660
2661         /* check direction of this stream */
2662         if (virtual_stream->stream_info->stream_conf_info.avail_in_devices[0] != NULL)
2663                 io_direction |= SOUND_STREAM_DIRECTION_INPUT;
2664         if (virtual_stream->stream_info->stream_conf_info.avail_out_devices[0] != NULL)
2665                 io_direction |= SOUND_STREAM_DIRECTION_OUTPUT;
2666
2667         pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
2668
2669         for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2670                 if (io_direction & (i + 1)) {
2671                         virtual_stream->pa_stream[i] = pa_stream_new_with_proplist(virtual_stream->pa_context, "VIRTUAL_STREAM", &ss, &maps, virtual_stream->pa_proplist);
2672                         if (virtual_stream->pa_stream[i] == NULL) {
2673                                 LOGE("failed to pa_stream_new_with_proplist()");
2674                                 pa_ret = pa_context_errno(virtual_stream->pa_context);
2675                                 ret = MM_ERROR_SOUND_INTERNAL;
2676                                 goto ERROR_WITH_UNLOCK;
2677                         }
2678                         pa_stream_set_state_callback(virtual_stream->pa_stream[i], _pa_stream_state_cb, virtual_stream);
2679
2680                         if ((i + 1) == SOUND_STREAM_DIRECTION_OUTPUT) {
2681                                 pa_ret = pa_stream_connect_playback(virtual_stream->pa_stream[i], NULL, NULL, 0, NULL, NULL);
2682                                 if (pa_ret < 0) {
2683                                         LOGE("failed to pa_stream_connect_playback()");
2684                                         pa_ret = pa_context_errno(virtual_stream->pa_context);
2685                                         ret = MM_ERROR_SOUND_INTERNAL;
2686                                         goto ERROR_WITH_UNLOCK;
2687                                 }
2688                         } else if ((i + 1) == SOUND_STREAM_DIRECTION_INPUT) {
2689                                 pa_ret = pa_stream_connect_record(virtual_stream->pa_stream[i], NULL, NULL, 0);
2690                                 if (pa_ret < 0) {
2691                                         LOGE("failed to pa_stream_connect_record()");
2692                                         pa_ret = pa_context_errno(virtual_stream->pa_context);
2693                                         ret = MM_ERROR_SOUND_INTERNAL;
2694                                         goto ERROR_WITH_UNLOCK;
2695                                 }
2696                         }
2697
2698                         /* wait for ready state of the stream */
2699                         for (;;) {
2700                                 pa_stream_state_t state;
2701                                 state = pa_stream_get_state(virtual_stream->pa_stream[i]);
2702                                 if (state == PA_STREAM_READY)
2703                                         break;
2704                                 if (!PA_STREAM_IS_GOOD(state)) {
2705                                         LOGE("stream(%d) is not good, state : %d", i, state);
2706                                         pa_ret = pa_context_errno(virtual_stream->pa_context);
2707                                         ret = MM_ERROR_SOUND_INTERNAL;
2708                                         goto ERROR_WITH_UNLOCK;
2709                                 }
2710
2711                                 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
2712                         }
2713                 }
2714         }
2715         virtual_stream->state = _VSTREAM_STATE_RUNNING;
2716
2717         pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2718
2719         return ret;
2720
2721 ERROR_WITH_UNLOCK:
2722         pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2723
2724         for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2725                 if (virtual_stream->pa_stream[i]) {
2726                         pa_stream_unref(virtual_stream->pa_stream[i]);
2727                         virtual_stream->pa_stream[i] = NULL;
2728                 }
2729         }
2730         LOGE("pa_ret(%d)", pa_ret);
2731         return ret;
2732 }
2733
2734 int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2735 {
2736         int ret = MM_ERROR_NONE;
2737         int i = 0;
2738
2739         SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2740         SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_RUNNING);
2741
2742         pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
2743
2744         for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2745                 if (virtual_stream->pa_stream[i]) {
2746                         pa_stream_disconnect(virtual_stream->pa_stream[i]);
2747
2748                         /* wait for terminated state of the stream */
2749                         for (;;) {
2750                                 pa_stream_state_t state;
2751                                 state = pa_stream_get_state(virtual_stream->pa_stream[i]);
2752                                 if (state == PA_STREAM_TERMINATED)
2753                                         break;
2754                                 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
2755                         }
2756
2757                         pa_stream_unref(virtual_stream->pa_stream[i]);
2758                         virtual_stream->pa_stream[i] = NULL;
2759                 }
2760         }
2761
2762         pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2763
2764         virtual_stream->state = _VSTREAM_STATE_READY;
2765
2766         return ret;
2767 }
2768
2769 int _set_volume_ratio(uint32_t stream_index, sound_stream_direction_e direction, double ratio)
2770 {
2771         int ret = MM_ERROR_NONE;
2772         GDBusConnection *conn = NULL;
2773         GError *err = NULL;
2774         GVariant *result = NULL;
2775         const gchar *dbus_ret = NULL;
2776
2777         if ((ret = __get_dbus_connection(&conn)))
2778                 return ret;
2779
2780         result = g_dbus_connection_call_sync(conn,
2781                                                 PA_BUS_NAME,
2782                                                 PA_STREAM_MANAGER_OBJECT_PATH,
2783                                                 PA_STREAM_MANAGER_INTERFACE,
2784                                                 PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATIO,
2785                                                 g_variant_new("(sud)", (direction == SOUND_STREAM_DIRECTION_OUTPUT) ? "out" : "in", stream_index, ratio),
2786                                                 G_VARIANT_TYPE("(s)"),
2787                                                 G_DBUS_CALL_FLAGS_NONE,
2788                                                 DBUS_METHOD_TIMEOUT,
2789                                                 NULL,
2790                                                 &err);
2791         if (!result || err) {
2792                 LOGE("g_dbus_connection_call_sync() for SET_VOLUME_RATIO error (%s)", err ? err->message : NULL);
2793                 ret = _convert_dbus_error(err ? err->message : NULL);
2794                 if (err)
2795                         g_error_free(err);
2796                 goto LEAVE;
2797         }
2798         g_variant_get(result, "(&s)", &dbus_ret);
2799         LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
2800         if (!strncmp("STREAM_MANAGER_RETURN_ERROR_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret)))
2801                 ret = MM_ERROR_INVALID_ARGUMENT;
2802         else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
2803                 ret = MM_ERROR_SOUND_NO_DATA;
2804         else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
2805                 ret = MM_ERROR_SOUND_INTERNAL;
2806
2807 LEAVE:
2808         g_variant_unref(result);
2809         g_object_unref(conn);
2810
2811         return ret;
2812 }
2813
2814 int _set_virtual_stream_volume(virtual_sound_stream_info_s *virtual_stream, double ratio)
2815 {
2816         int ret = MM_ERROR_NONE;
2817         int i = 0;
2818         uint32_t index;
2819
2820         SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2821         SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_RUNNING);
2822
2823         pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
2824
2825         for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2826                 if (virtual_stream->pa_stream[i]) {
2827                         index = pa_stream_get_index(virtual_stream->pa_stream[i]);
2828                         if ((ret = _set_volume_ratio(index, i + 1, ratio))) {
2829                                 if (ret == MM_ERROR_SOUND_NO_DATA) {
2830                                         LOGE("something wrong, no match index of %u", index);
2831                                         ret = MM_ERROR_SOUND_INTERNAL;
2832                                 }
2833                                 break;
2834                         }
2835                 }
2836         }
2837
2838         pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2839
2840         return ret;
2841 }
2842
2843 int _set_acm_master_mode(bool on)
2844 {
2845         int ret = MM_ERROR_NONE;
2846         GVariant *result = NULL;
2847         GDBusConnection *conn = NULL;
2848         GError *err = NULL;
2849
2850         if ((ret = __get_dbus_connection(&conn)))
2851                 return ret;
2852
2853         result = g_dbus_connection_call_sync(conn,
2854                                                                           PA_BUS_NAME,
2855                                                                           PA_DEVICE_MANAGER_OBJECT_PATH,
2856                                                                           PA_DEVICE_MANAGER_INTERFACE,
2857                                                                           PA_DEVICE_MANAGER_METHOD_NAME_SET_ACM_MODE,
2858                                                                           g_variant_new("(u)", (unsigned int)on),
2859                                                                           NULL,
2860                                                                           G_DBUS_CALL_FLAGS_NONE,
2861                                                                           DBUS_METHOD_TIMEOUT,
2862                                                                           NULL,
2863                                                                           &err);
2864         if (err) {
2865                 LOGE("g_dbus_connection_call_sync() for SET ACM MODE error (%s)", err->message);
2866                 ret = _convert_dbus_error(err->message);
2867                 g_error_free(err);
2868                 goto LEAVE;
2869         } else {
2870                 LOGI("ACM master mode [%s]", on ? "ON" : "OFF");
2871         }
2872
2873 LEAVE:
2874         g_variant_unref(result);
2875         g_object_unref(conn);
2876
2877         return ret;
2878 }
2879
2880 int _activate_ducking(uint32_t stream_index, bool enable, const char *target_stream, uint32_t duration, double ratio)
2881 {
2882         int ret = MM_ERROR_NONE;
2883         GDBusConnection *conn = NULL;
2884         GError *err = NULL;
2885         GVariant *result = NULL;
2886         const gchar *dbus_ret = NULL;
2887
2888         if ((ret = __get_dbus_connection(&conn)))
2889                 return ret;
2890
2891         result = g_dbus_connection_call_sync(conn,
2892                 PA_BUS_NAME,
2893                 PA_STREAM_MANAGER_OBJECT_PATH,
2894                 PA_STREAM_MANAGER_INTERFACE,
2895                 PA_STREAM_MANAGER_METHOD_NAME_ACTIVATE_DUCKING,
2896                 g_variant_new("(ubsud)", stream_index, enable, target_stream, duration, ratio),
2897                 G_VARIANT_TYPE("(s)"),
2898                 G_DBUS_CALL_FLAGS_NONE,
2899                 DBUS_METHOD_TIMEOUT,
2900                 NULL,
2901                 &err);
2902         if (!result || err) {
2903                 LOGE("g_dbus_connection_call_sync() for ACTIVATE_DUCKING error");
2904                 ret = _convert_dbus_error(err ? err->message : NULL);
2905                 if (err)
2906                         g_error_free(err);
2907                 goto LEAVE;
2908         }
2909
2910         g_variant_get(result, "(&s)", &dbus_ret);
2911
2912         LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
2913
2914         if (!strncmp("STREAM_MANAGER_RETURN_ERROR_INVALID_STATE", dbus_ret, strlen(dbus_ret)))
2915                 ret = MM_ERROR_SOUND_INVALID_STATE;
2916         else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
2917                 ret = MM_ERROR_SOUND_INTERNAL;
2918
2919 LEAVE:
2920         g_variant_unref(result);
2921         g_object_unref(conn);
2922
2923         return ret;
2924 }
2925
2926 int _get_ducking_state(sound_pa_info_s *pa_info, bool *is_ducked)
2927 {
2928         int ret = MM_ERROR_NONE;
2929         gboolean _is_ducked = FALSE;
2930         GDBusConnection *conn = NULL;
2931         GError *err = NULL;
2932         GVariant *result = NULL;
2933         const gchar *dbus_ret = NULL;
2934
2935         SM_NULL_ARG_CHECK_FOR_PRIV(pa_info);
2936         SM_NULL_ARG_CHECK_FOR_PRIV(is_ducked);
2937
2938         if (pa_info->is_disconnected) {
2939                 LOGE("server disconnected");
2940                 return MM_ERROR_SOUND_SERVER_DISCONNECTED;
2941         }
2942
2943         if ((ret = __get_dbus_connection(&conn)))
2944                 return ret;
2945
2946         result = g_dbus_connection_call_sync(conn,
2947                 PA_BUS_NAME,
2948                 PA_STREAM_MANAGER_OBJECT_PATH,
2949                 PA_STREAM_MANAGER_INTERFACE,
2950                 PA_STREAM_MANAGER_METHOD_NAME_GET_DUCKING_STATE,
2951                 g_variant_new("(u)", pa_info->index),
2952                 G_VARIANT_TYPE("(bs)"),
2953                 G_DBUS_CALL_FLAGS_NONE,
2954                 DBUS_METHOD_TIMEOUT,
2955                 NULL,
2956                 &err);
2957         if (!result || err) {
2958                 LOGE("g_dbus_connection_call_sync() for GET_DUCKING_STATE error");
2959                 ret = _convert_dbus_error(err ? err->message : NULL);
2960                 if (err)
2961                         g_error_free(err);
2962                 goto LEAVE;
2963         }
2964
2965         g_variant_get(result, "(b&s)", &_is_ducked, &dbus_ret);
2966
2967         LOGI("dbus return value is (%s)", dbus_ret);
2968
2969         if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
2970                 *is_ducked = (bool)_is_ducked;
2971                 LOGI("is_ducked %u", *is_ducked);
2972         } else {
2973                 ret = MM_ERROR_SOUND_INTERNAL;
2974         }
2975
2976         if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
2977                 ret = MM_ERROR_SOUND_INTERNAL;
2978
2979 LEAVE:
2980         g_variant_unref(result);
2981         g_object_unref(conn);
2982
2983         return ret;
2984 }
2985
2986 static int __invoke_ipc_set_preferred_device_id(sound_stream_info_s *stream_info, int device_id, sound_device_io_direction_e io_direction, sound_device_io_direction_e req_direction)
2987 {
2988         int ret = SOUND_MANAGER_ERROR_NONE;
2989         GVariant *result = NULL;
2990         GDBusConnection *conn = NULL;
2991         GError *err = NULL;
2992         const gchar *dbus_ret = NULL;
2993         const gchar *direction_str;
2994         int i;
2995
2996         SM_ARG_CHECK(stream_info);
2997
2998         if ((ret = __get_dbus_connection(&conn)))
2999                 return SOUND_MANAGER_ERROR_INTERNAL;
3000
3001         for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
3002                 if (device_id) {
3003                         if (!(io_direction & (i + 1)))
3004                                 continue;
3005                 } else {
3006                         if (!((req_direction + 1) & (i + 1)))
3007                                 continue;
3008                 }
3009                 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3010
3011                 result = g_dbus_connection_call_sync(conn,
3012                         PA_BUS_NAME,
3013                         PA_STREAM_MANAGER_OBJECT_PATH,
3014                         PA_STREAM_MANAGER_INTERFACE,
3015                         PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE,
3016                         g_variant_new("(usu)", stream_info->pa_info.index, direction_str, (unsigned int)device_id),
3017                         NULL,
3018                         G_DBUS_CALL_FLAGS_NONE,
3019                         DBUS_METHOD_TIMEOUT,
3020                         NULL,
3021                         &err);
3022                 if (!result || err) {
3023                         LOGE("g_dbus_connection_call_sync() for SET PREFERRED DEVICE error (%s)", err ? err->message : NULL);
3024                         ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3025                         if (err)
3026                                 g_error_free(err);
3027                         if (result)
3028                                 g_variant_unref(result);
3029                         goto LEAVE;
3030                 }
3031
3032                 LOGI("Preferred device(id:%d, direction:%s) is set to PA context(%u)", device_id, direction_str, stream_info->pa_info.index);
3033
3034                 g_variant_get(result, "(&s)", &dbus_ret);
3035                 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
3036                 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_DEVICE_NOT_FOUND", dbus_ret, strlen(dbus_ret)))
3037                         ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3038                 else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
3039                         ret = SOUND_MANAGER_ERROR_POLICY;
3040                 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3041                         ret = SOUND_MANAGER_ERROR_INTERNAL;
3042
3043                 g_variant_unref(result);
3044                 if (ret)
3045                         goto LEAVE;
3046
3047                 if (i == SOUND_DEVICE_IO_DIRECTION_IN)
3048                         stream_info->preferred_device_info.in = device_id;
3049                 else
3050                         stream_info->preferred_device_info.out = device_id;
3051         }
3052
3053 LEAVE:
3054         g_object_unref(conn);
3055         return ret;
3056 }
3057
3058 int _set_preferred_device(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, sound_device_h device)
3059 {
3060         int ret = SOUND_MANAGER_ERROR_NONE;
3061         int mm_ret = MM_ERROR_NONE;
3062         bool available = false;
3063         int device_id = 0;
3064         mm_sound_device_io_direction_e io_direction = MM_SOUND_DEVICE_IO_DIRECTION_IN;
3065
3066         SM_ARG_CHECK(stream_info);
3067
3068         /* allow only auto route type */
3069         if ((ret = __check_auto_route_type(stream_info)))
3070                 return ret;
3071
3072         /* check if this device belongs to available devices of the stream info */
3073         /* In case device is null, it's for unsetting preferred device, device_id will be 0. */
3074         if (device) {
3075                 if ((ret = __is_available_device(stream_info, device, &available)))
3076                         return ret;
3077                 if (!available)
3078                         return SOUND_MANAGER_ERROR_POLICY;
3079                 if ((mm_ret = mm_sound_get_device_id(device, &device_id)))
3080                         return _convert_sound_manager_error_code(__func__, mm_ret);
3081                 if ((mm_ret = mm_sound_get_device_io_direction(device, &io_direction)))
3082                         return _convert_sound_manager_error_code(__func__, mm_ret);
3083                 if (!(io_direction & (direction + 1)) || ((int)io_direction < (int)(direction + 1))) {
3084                         LOGE("device direction(0x%x), request direction(0x%x)", io_direction, (direction + 1));
3085                         return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3086                 }
3087         }
3088
3089         return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3090 }
3091
3092 int _set_preferred_device_id(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, int device_id)
3093 {
3094         int ret = SOUND_MANAGER_ERROR_NONE;
3095         int mm_ret = MM_ERROR_NONE;
3096         bool available = false;
3097         mm_sound_device_io_direction_e io_direction = MM_SOUND_DEVICE_IO_DIRECTION_IN;
3098
3099         SM_ARG_CHECK(stream_info);
3100
3101         /* allow only auto route type */
3102         if ((ret = __check_auto_route_type(stream_info)))
3103                 return ret;
3104
3105         /* check if this device belongs to available devices of the stream info */
3106         /* In case device_id is 0, it's for unsetting preferred device. */
3107         if (device_id) {
3108                 MMSoundDevice_t device = NULL;
3109
3110                 if ((mm_ret = mm_sound_get_device_by_id(device_id, &device))) {
3111                         LOGE("failed to mm_sound_get_device_by_id()");
3112                         return _convert_sound_manager_error_code(__func__, mm_ret);
3113                 }
3114                 if ((ret = __is_available_device(stream_info, (sound_device_h)device, &available)))
3115                         goto device_free;
3116                 if (!available) {
3117                         ret = SOUND_MANAGER_ERROR_POLICY;
3118                         goto device_free;
3119                 }
3120                 if ((mm_ret = mm_sound_get_device_io_direction(device, &io_direction))) {
3121                         ret = _convert_sound_manager_error_code(__func__, mm_ret);
3122                         goto  device_free;
3123                 }
3124                 if (!(io_direction & (direction + 1)) || ((int)io_direction < (int)(direction + 1))) {
3125                         LOGE("device direction(0x%x), request direction(0x%x)", io_direction, (direction + 1));
3126                         ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3127                 }
3128 device_free:
3129                 mm_sound_free_device(device);
3130                 if (ret)
3131                         return ret;
3132         }
3133
3134         return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3135 }
3136
3137 int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id)
3138 {
3139         int ret = SOUND_MANAGER_ERROR_NONE;
3140         GDBusConnection *conn = NULL;
3141         GError *err = NULL;
3142         GVariant *result = NULL;
3143         const gchar *dbus_ret = NULL;
3144         unsigned int _in_device_id;
3145         unsigned int _out_device_id;
3146
3147         SM_ARG_CHECK(stream_info);
3148
3149         if ((ret = __get_dbus_connection(&conn)))
3150                 return SOUND_MANAGER_ERROR_INTERNAL;
3151
3152         result = g_dbus_connection_call_sync(conn,
3153                 PA_BUS_NAME,
3154                 PA_STREAM_MANAGER_OBJECT_PATH,
3155                 PA_STREAM_MANAGER_INTERFACE,
3156                 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE,
3157                 g_variant_new("(u)", stream_info->pa_info.index),
3158                 G_VARIANT_TYPE("(uus)"),
3159                 G_DBUS_CALL_FLAGS_NONE,
3160                 DBUS_METHOD_TIMEOUT,
3161                 NULL,
3162                 &err);
3163         if (!result || err) {
3164                 LOGE("g_dbus_connection_call_sync() for GET_STREAM_PREFERRED_DEVICE error");
3165                 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3166                 if (err)
3167                         g_error_free(err);
3168                 goto LEAVE;
3169         }
3170
3171         g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3172
3173         LOGI("dbus return value is (%s)", dbus_ret);
3174
3175         if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3176                 if (in_device_id) {
3177                         if (stream_info->preferred_device_info.in != _in_device_id) {
3178                                 LOGE("mismatching id [prev: %d, curr: %d]", stream_info->preferred_device_info.in, _in_device_id);
3179                                 ret = SOUND_MANAGER_ERROR_INTERNAL;
3180                         } else {
3181                                 *in_device_id = _in_device_id;
3182                                 LOGI("preferred device id[in:%d]", *in_device_id);
3183                         }
3184                 }
3185                 if (out_device_id) {
3186                         if (stream_info->preferred_device_info.out != _out_device_id) {
3187                                 LOGE("mismatching id [prev: %d, curr: %d]", stream_info->preferred_device_info.out, _out_device_id);
3188                                 ret = SOUND_MANAGER_ERROR_INTERNAL;
3189                         } else {
3190                                 *out_device_id = _out_device_id;
3191                                 LOGI("preferred device id[out:%d]", *out_device_id);
3192                         }
3193                 }
3194         } else {
3195                 ret = SOUND_MANAGER_ERROR_INTERNAL;
3196         }
3197
3198 LEAVE:
3199         g_variant_unref(result);
3200         g_object_unref(conn);
3201
3202         return ret;
3203 }
3204
3205 static int __invoke_ipc_set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e io_direction, int device_id)
3206 {
3207         int ret = MM_ERROR_NONE;
3208         GVariant *result = NULL;
3209         GDBusConnection *conn = NULL;
3210         GError *err = NULL;
3211         const gchar *dbus_ret = NULL;
3212         const gchar *direction_str;
3213         char *stream_type_str;
3214         int i;
3215
3216         if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != MM_ERROR_NONE)
3217                 return ret;
3218
3219         if ((ret = __get_dbus_connection(&conn)))
3220                 return ret;
3221
3222         for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
3223                 if (io_direction != SOUND_DEVICE_IO_DIRECTION_BOTH && io_direction != i)
3224                         continue;
3225                 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3226
3227                 result = g_dbus_connection_call_sync(conn,
3228                         PA_BUS_NAME,
3229                         PA_STREAM_MANAGER_OBJECT_PATH,
3230                         PA_STREAM_MANAGER_INTERFACE,
3231                         PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREEMPTIVE_DEVICE,
3232                         g_variant_new("(ssu)", stream_type_str, direction_str, (unsigned int)device_id),
3233                         NULL,
3234                         G_DBUS_CALL_FLAGS_NONE,
3235                         DBUS_METHOD_TIMEOUT,
3236                         NULL,
3237                         &err);
3238                 if (!result || err) {
3239                         LOGE("g_dbus_connection_call_sync() for SET_STREAM_PREEMPTIVE_DEVICE, direction(%s) error (%s)",
3240                                         direction_str, err ? err->message : NULL);
3241                         ret = _convert_dbus_error(err ? err->message : NULL);
3242                         if (err)
3243                                 g_error_free(err);
3244                         if (result)
3245                                 g_variant_unref(result);
3246                         continue;
3247                 }
3248
3249                 LOGI("Preemptive device(id:%d, direction:%s) is set", device_id, direction_str);
3250
3251                 g_variant_get(result, "(&s)", &dbus_ret);
3252                 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
3253                 if (!strncmp("STREAM_MANAGER_RETURN_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret)))
3254                         ret = MM_ERROR_INVALID_ARGUMENT;
3255                 else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
3256                         ret = MM_ERROR_POLICY_INTERNAL;
3257                 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3258                         ret = MM_ERROR_SOUND_INTERNAL;
3259
3260                 g_variant_unref(result);
3261                 if (ret)
3262                         goto LEAVE;
3263         }
3264
3265 LEAVE:
3266         g_object_unref(conn);
3267         return ret;
3268 }
3269
3270 static int __invoke_ipc_get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3271 {
3272         int ret = MM_ERROR_NONE;
3273         GDBusConnection *conn = NULL;
3274         GError *err = NULL;
3275         GVariant *result = NULL;
3276         const gchar *dbus_ret = NULL;
3277         unsigned int _in_device_id;
3278         unsigned int _out_device_id;
3279         char *stream_type_str;
3280
3281         if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != MM_ERROR_NONE)
3282                 return ret;
3283
3284         if ((ret = __get_dbus_connection(&conn)))
3285                 return ret;
3286
3287         result = g_dbus_connection_call_sync(conn,
3288                 PA_BUS_NAME,
3289                 PA_STREAM_MANAGER_OBJECT_PATH,
3290                 PA_STREAM_MANAGER_INTERFACE,
3291                 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREEMPTIVE_DEVICE,
3292                 g_variant_new("(s)", stream_type_str),
3293                 G_VARIANT_TYPE("(uus)"),
3294                 G_DBUS_CALL_FLAGS_NONE,
3295                 DBUS_METHOD_TIMEOUT,
3296                 NULL,
3297                 &err);
3298         if (!result || err) {
3299                 LOGE("g_dbus_connection_call_sync() for GET_STREAM_PREEMPTIVE_DEVICE error");
3300                 ret = _convert_dbus_error(err ? err->message : NULL);
3301                 if (err)
3302                         g_error_free(err);
3303                 goto LEAVE;
3304         }
3305         g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3306
3307         LOGI("dbus return value is (%s)", dbus_ret);
3308
3309         if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3310                 if (in_device_id) {
3311                         *in_device_id = _in_device_id;
3312                         LOGI("preemptive device id[in:%d]", *in_device_id);
3313                 }
3314                 if (out_device_id) {
3315                         *out_device_id = _out_device_id;
3316                         LOGI("preemptive device id[out:%d]", *out_device_id);
3317                 }
3318         } else {
3319                 ret = MM_ERROR_SOUND_INTERNAL;
3320         }
3321
3322 LEAVE:
3323         g_variant_unref(result);
3324         g_object_unref(conn);
3325
3326         return ret;
3327 }
3328
3329 int _set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id)
3330 {
3331         return __invoke_ipc_set_preemptive_device(stream_type, direction, device_id);
3332 }
3333
3334 int _get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3335 {
3336         return __invoke_ipc_get_preemptive_device(stream_type, in_device_id, out_device_id);
3337 }
3338
3339 int _get_latest_stream_pid(int stream_type, unsigned int *pid)
3340 {
3341         int ret = MM_ERROR_NONE;
3342         GDBusConnection *conn = NULL;
3343         GError *err = NULL;
3344         GVariant *result = NULL;
3345         GVariantBuilder *builder_for_stream_types;
3346         const gchar *dbus_ret = NULL;
3347         unsigned int _pid;
3348
3349         SM_NULL_ARG_CHECK_FOR_PRIV(pid);
3350
3351         if ((ret = __get_dbus_connection(&conn)))
3352                 return ret;
3353
3354         builder_for_stream_types = g_variant_builder_new(G_VARIANT_TYPE("as"));
3355         if (!builder_for_stream_types) {
3356                 LOGE("failed to g_variant_builder_new()");
3357                 ret = MM_ERROR_SOUND_INTERNAL;
3358                 goto LEAVE;
3359         }
3360
3361         if (stream_type & STREAM_TYPE_MEDIA)
3362                 g_variant_builder_add(builder_for_stream_types, "s", STREAM_MEDIA);
3363         if (stream_type & STREAM_TYPE_SYSTEM)
3364                 g_variant_builder_add(builder_for_stream_types, "s", STREAM_SYSTEM);
3365         if (stream_type & STREAM_TYPE_ALARM)
3366                 g_variant_builder_add(builder_for_stream_types, "s", STREAM_ALARM);
3367         if (stream_type & STREAM_TYPE_NOTIFICATION)
3368                 g_variant_builder_add(builder_for_stream_types, "s", STREAM_NOTIFICATION);
3369         if (stream_type & STREAM_TYPE_EMERGENCY)
3370                 g_variant_builder_add(builder_for_stream_types, "s", STREAM_EMERGENCY);
3371         if (stream_type & STREAM_TYPE_VOICE_INFORMATION)
3372                 g_variant_builder_add(builder_for_stream_types, "s", STREAM_VOICE_INFORMATION);
3373
3374         result = g_dbus_connection_call_sync(conn,
3375                 PA_BUS_NAME,
3376                 PA_STREAM_MANAGER_OBJECT_PATH,
3377                 PA_STREAM_MANAGER_INTERFACE,
3378                 PA_STREAM_MANAGER_METHOD_NAME_GET_LASTEST_STREAM_PID,
3379                 g_variant_new("(sas)", "out", builder_for_stream_types),
3380                 G_VARIANT_TYPE("(us)"),
3381                 G_DBUS_CALL_FLAGS_NONE,
3382                 DBUS_METHOD_TIMEOUT,
3383                 NULL,
3384                 &err);
3385         if (!result || err) {
3386                 LOGE("g_dbus_connection_call_sync() for GET_LASTEST_STREAM_PID error");
3387                 ret = _convert_dbus_error(err ? err->message : NULL);
3388                 if (err)
3389                         g_error_free(err);
3390                 goto LEAVE;
3391         }
3392
3393         g_variant_get(result, "(u&s)", &_pid, &dbus_ret);
3394
3395         LOGI("dbus return value is (%s)", dbus_ret);
3396
3397         if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3398                 *pid = _pid;
3399         else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
3400                 ret = MM_ERROR_SOUND_NO_DATA;
3401         else
3402                 ret = MM_ERROR_SOUND_INTERNAL;
3403
3404 LEAVE:
3405         if (builder_for_stream_types)
3406                 g_variant_builder_unref(builder_for_stream_types);
3407         g_variant_unref(result);
3408         g_object_unref(conn);
3409
3410         return ret;
3411 }
3412 //LCOV_EXCL_STOP