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