2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <sound_manager.h>
18 #include <sound_manager_private.h>
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"
44 #define DBUS_METHOD_TIMEOUT 5000
46 #define PA_BUS_NAME "org.pulseaudio.Server"
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"
72 #define PA_STREAM_MANAGER_SIGNAL_NAME_REMOTE_FOUND "RemoteFound"
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"
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"
95 #define VCONF_PATH_PREFIX_VOLUME "file/private/sound/volume/"
96 #define VCONF_PATH_MAX 64
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))) \
109 #define SM_INTERNAL_SOUND_TYPE_CHECK(x_sound_type, x_error) \
110 if (!strncmp(x_sound_type, "bixby", strlen(x_sound_type))) \
114 int _convert_dbus_error(const char *error_msg)
116 int ret = MM_ERROR_NONE;
119 return MM_ERROR_SOUND_INTERNAL;
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;
130 ret = MM_ERROR_SOUND_INTERNAL;
132 LOGE("%s => 0x%x", error_msg, ret);
138 int _convert_sound_manager_error_code(const char *func, int code)
140 int ret = SOUND_MANAGER_ERROR_NONE;
141 char *errorstr = NULL;
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";
151 ret = SOUND_MANAGER_ERROR_NONE;
152 errorstr = "ERROR_NONE";
154 case MM_ERROR_INVALID_ARGUMENT:
155 case MM_ERROR_SOUND_INVALID_POINTER:
156 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
157 errorstr = "INVALID_PARAMETER";
159 case MM_ERROR_SOUND_PERMISSION_DENIED:
161 ret = SOUND_MANAGER_ERROR_PERMISSION_DENIED;
162 errorstr = "PERMISSION_DENIED";
165 case MM_ERROR_SOUND_NO_DATA:
166 ret = SOUND_MANAGER_ERROR_NO_DATA;
167 errorstr = "NO_DATA";
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:
174 ret = SOUND_MANAGER_ERROR_INTERNAL;
175 errorstr = "INTERNAL";
178 case MM_ERROR_POLICY_DUPLICATED:
179 case MM_ERROR_POLICY_INTERNAL:
180 case MM_ERROR_POLICY_BLOCKED:
181 ret = SOUND_MANAGER_ERROR_POLICY;
184 case MM_ERROR_SOUND_VOLUME_NO_INSTANCE:
185 ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
186 errorstr = "NO_PLAYING_SOUND";
188 case MM_ERROR_NOT_SUPPORT_API:
189 ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
190 errorstr = "NOT_SUPPORTED";
192 case MM_ERROR_SOUND_INVALID_STATE:
193 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
194 errorstr = "INVALID_STATE";
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";
205 LOGE("[%s] >> leave : %s(0x%08x), mm_error(0x%08x)", func, errorstr, ret, code);
207 LOGD("[%s] >> leave : %s(0x%08x)", func, errorstr, ret);
212 int _convert_stream_type(sound_stream_type_e stream_type_enum, char **stream_type)
214 SM_ARG_CHECK(stream_type);
216 switch (stream_type_enum) {
217 case SOUND_STREAM_TYPE_MEDIA:
218 *stream_type = STREAM_MEDIA;
220 case SOUND_STREAM_TYPE_SYSTEM:
221 *stream_type = STREAM_SYSTEM;
223 case SOUND_STREAM_TYPE_ALARM:
224 *stream_type = STREAM_ALARM;
226 case SOUND_STREAM_TYPE_NOTIFICATION:
227 *stream_type = STREAM_NOTIFICATION;
229 case SOUND_STREAM_TYPE_EMERGENCY:
230 *stream_type = STREAM_EMERGENCY;
232 case SOUND_STREAM_TYPE_VOICE_INFORMATION:
233 *stream_type = STREAM_VOICE_INFORMATION;
235 case SOUND_STREAM_TYPE_VOICE_RECOGNITION:
236 *stream_type = STREAM_VOICE_RECOGNITION;
238 case SOUND_STREAM_TYPE_RINGTONE_VOIP:
239 *stream_type = STREAM_RINGTONE_VOIP;
241 case SOUND_STREAM_TYPE_VOIP:
242 *stream_type = STREAM_VOIP;
244 case SOUND_STREAM_TYPE_MEDIA_EXTERNAL_ONLY:
245 *stream_type = STREAM_EXT_MEDIA;
249 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
250 return SOUND_MANAGER_ERROR_INTERNAL;
254 LOGI("stream_type[%s]", *stream_type);
256 return SOUND_MANAGER_ERROR_NONE;
260 int _convert_stream_type_for_internal(sound_stream_type_internal_e stream_type_enum, char **stream_type)
262 SM_ARG_CHECK(stream_type);
264 switch (stream_type_enum) {
265 case SOUND_STREAM_TYPE_RINGTONE_CALL:
266 *stream_type = STREAM_RINGTONE_CALL;
268 case SOUND_STREAM_TYPE_RINGBACKTONE_CALL:
269 *stream_type = STREAM_RINGBACKTONE_CALL;
271 case SOUND_STREAM_TYPE_VOICE_CALL:
272 *stream_type = STREAM_CALL_VOICE;
274 case SOUND_STREAM_TYPE_VIDEO_CALL:
275 *stream_type = STREAM_CALL_VIDEO;
277 case SOUND_STREAM_TYPE_RADIO:
278 *stream_type = STREAM_RADIO;
280 case SOUND_STREAM_TYPE_LOOPBACK:
281 *stream_type = STREAM_LOOPBACK;
283 case SOUND_STREAM_TYPE_LOOPBACK_MIRRORING:
284 *stream_type = STREAM_LOOPBACK_MIRRORING;
286 case SOUND_STREAM_TYPE_SOLO:
287 *stream_type = STREAM_SOLO;
289 case SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE:
290 *stream_type = STREAM_VOICE_RECOGNITION_SERVICE;
292 case SOUND_STREAM_TYPE_MEDIA_COMPRESSED:
293 *stream_type = STREAM_COMPRESSED_MEDIA;
295 #ifndef TIZEN_FEATURE_TV_PROD
296 case SOUND_STREAM_TYPE_MEDIA_NETWORK_SOURCE:
297 *stream_type = STREAM_NETWORK_SOURCE_MEDIA;
301 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
302 return SOUND_MANAGER_ERROR_INTERNAL;
304 LOGI("stream_type_for_internal[%s]", *stream_type);
306 return SOUND_MANAGER_ERROR_NONE;
309 void _set_focus_availability(sound_stream_info_s *stream_info)
311 if (stream_info == NULL || stream_info->stream_type == NULL) {
312 LOGE("invalid argument");
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);
326 int _convert_stream_type_to_change_reason(const char *stream_type, sound_stream_focus_change_reason_e *change_reason)
328 SM_ARG_CHECK(stream_type);
329 SM_ARG_CHECK(change_reason);
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;
337 } else if (!strncmp(stream_type, STREAM_SYSTEM, SOUND_STREAM_TYPE_LEN)) {
338 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM;//LCOV_EXCL_LINE
340 } else if (!strncmp(stream_type, STREAM_ALARM, SOUND_STREAM_TYPE_LEN)) {
341 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_ALARM;
343 } else if (!strncmp(stream_type, STREAM_NOTIFICATION, SOUND_STREAM_TYPE_LEN)) {
344 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION;
346 } else if (!strncmp(stream_type, STREAM_EMERGENCY, SOUND_STREAM_TYPE_LEN)) {
347 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY;//LCOV_EXCL_LINE
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
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;
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;
361 } else if (!strncmp(stream_type, STREAM_VOIP, SOUND_STREAM_TYPE_LEN)) {
362 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOIP;
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
368 } else if (!strncmp(stream_type, STREAM_EXT_MEDIA, SOUND_STREAM_TYPE_LEN)) {
369 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY;
373 LOGE("not supported stream_type(%s)", stream_type);
374 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
378 return SOUND_MANAGER_ERROR_NONE;
381 static int __get_dbus_connection(GDBusConnection **conn)
385 *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
386 if (!(*conn) || err) {
388 LOGE("g_bus_get_sync() error (%s)", err ? err->message : NULL);
391 return SOUND_MANAGER_ERROR_INTERNAL;
395 return SOUND_MANAGER_ERROR_NONE;
398 int _convert_sound_type(sound_type_e sound_type, const char **volume_type)
400 SM_ARG_CHECK(volume_type);
402 switch (sound_type) {
403 case SOUND_TYPE_SYSTEM:
404 *volume_type = "system";
406 case SOUND_TYPE_NOTIFICATION:
407 *volume_type = "notification";
409 case SOUND_TYPE_ALARM:
410 *volume_type = "alarm";
412 case SOUND_TYPE_RINGTONE:
413 *volume_type = "ringtone";
415 case SOUND_TYPE_MEDIA:
416 *volume_type = "media";
418 case SOUND_TYPE_CALL:
419 *volume_type = "call";
421 case SOUND_TYPE_VOIP:
422 *volume_type = "voip";
424 case SOUND_TYPE_VOICE:
425 *volume_type = "voice";
428 LOGI("volume_type[%s]", *volume_type);
430 return SOUND_MANAGER_ERROR_NONE;
434 int _convert_sound_type_for_internal(sound_type_internal_e sound_type, const char **volume_type)
436 SM_ARG_CHECK(volume_type);
438 switch (sound_type) {
439 case SOUND_TYPE_BIXBY:
440 *volume_type = "bixby";
443 LOGI("volume_type[%s]", *volume_type);
445 return SOUND_MANAGER_ERROR_NONE;
449 int _convert_sound_type_to_enum(const char *sound_type, sound_type_e *sound_type_enum)
451 SM_ARG_CHECK(sound_type);
452 SM_ARG_CHECK(sound_type_enum);
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;
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;
478 return SOUND_MANAGER_ERROR_NONE;
481 int _convert_sound_type_to_enum_for_internal(const char *sound_type, sound_type_internal_e *sound_type_enum)
483 SM_ARG_CHECK(sound_type);
484 SM_ARG_CHECK(sound_type_enum);
486 if (!strncmp(sound_type, "bixby", strlen(sound_type))) {
487 *sound_type_enum = SOUND_TYPE_BIXBY;
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;
494 return SOUND_MANAGER_ERROR_NONE;
497 int _convert_device_type_enum_to_str(sound_device_type_e device_type, char **device_type_str)
499 SM_ARG_CHECK(device_type_str);
501 switch (device_type) {
502 case SOUND_DEVICE_BUILTIN_SPEAKER:
503 *device_type_str = "builtin-speaker";
505 case SOUND_DEVICE_BUILTIN_RECEIVER:
506 *device_type_str = "builtin-receiver";
508 case SOUND_DEVICE_BUILTIN_MIC:
509 *device_type_str = "builtin-mic";
511 case SOUND_DEVICE_AUDIO_JACK:
512 *device_type_str = "audio-jack";
514 case SOUND_DEVICE_BLUETOOTH_MEDIA:
515 *device_type_str = "bt-a2dp";
517 case SOUND_DEVICE_BLUETOOTH_VOICE:
518 *device_type_str = "bt-sco";
520 case SOUND_DEVICE_HDMI:
521 *device_type_str = "hdmi";
523 case SOUND_DEVICE_USB_AUDIO:
524 *device_type_str = "usb-audio";
526 case SOUND_DEVICE_FORWARDING:
527 *device_type_str = "forwarding";
529 case SOUND_DEVICE_NETWORK:
530 *device_type_str = "network";
533 LOGE("could not find the device_type[%d] in this switch case statement", device_type);
534 return SOUND_MANAGER_ERROR_INTERNAL;
537 LOGI("device_type[%s]", *device_type_str);
539 return SOUND_MANAGER_ERROR_NONE;
542 int _convert_device_type_str_to_enum(const char *device_type_str, sound_device_type_e *device_type)
544 SM_ARG_CHECK(device_type_str);
545 SM_ARG_CHECK(device_type);
547 if (!strncmp(device_type_str, "builtin-speaker", SOUND_DEVICE_TYPE_LEN)) {
548 *device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
550 } else if (!strncmp(device_type_str, "builtin-receiver", SOUND_DEVICE_TYPE_LEN)) {
551 *device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
553 } else if (!strncmp(device_type_str, "builtin-mic", SOUND_DEVICE_TYPE_LEN)) {
554 *device_type = SOUND_DEVICE_BUILTIN_MIC;
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;
561 } else if (!strncmp(device_type_str, "usb-audio", SOUND_DEVICE_TYPE_LEN)) {
562 *device_type = SOUND_DEVICE_USB_AUDIO;
564 } else if (!strncmp(device_type_str, "bt-a2dp", SOUND_DEVICE_TYPE_LEN)) {
565 *device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
567 } else if (!strncmp(device_type_str, "bt-sco", SOUND_DEVICE_TYPE_LEN)) {
568 *device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
570 } else if (!strncmp(device_type_str, "network", SOUND_DEVICE_TYPE_LEN)) {
571 *device_type = SOUND_DEVICE_NETWORK;
574 LOGE("not supported device_type(%s)", device_type_str);
575 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
578 LOGI("device_type[%s, %d]", device_type_str, *device_type);
580 return SOUND_MANAGER_ERROR_NONE;
583 int _convert_device_type(mm_sound_device_type_e device_type, sound_device_type_e *sound_device_type)
585 SM_ARG_CHECK(sound_device_type);
587 switch (device_type) {
588 case MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER:
589 *sound_device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
591 case MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER:
592 *sound_device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
594 case MM_SOUND_DEVICE_TYPE_BUILTIN_MIC:
595 *sound_device_type = SOUND_DEVICE_BUILTIN_MIC;
598 case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
599 *sound_device_type = SOUND_DEVICE_AUDIO_JACK;
601 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP:
602 *sound_device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
604 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_SCO:
605 *sound_device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
607 case MM_SOUND_DEVICE_TYPE_HDMI:
608 *sound_device_type = SOUND_DEVICE_HDMI;
610 case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
611 *sound_device_type = SOUND_DEVICE_USB_AUDIO;
613 case MM_SOUND_DEVICE_TYPE_MIRRORING:
614 *sound_device_type = SOUND_DEVICE_FORWARDING;
616 case MM_SOUND_DEVICE_TYPE_NETWORK:
617 *sound_device_type = SOUND_DEVICE_NETWORK;
620 LOGE("not supported device_type(%d)", device_type);
621 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
625 LOGI("device_type[%d]", *sound_device_type);
627 return SOUND_MANAGER_ERROR_NONE;
630 int _convert_device_io_direction(mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *device_io_direction)
632 SM_ARG_CHECK(device_io_direction);
634 switch (io_direction) {
635 case MM_SOUND_DEVICE_IO_DIRECTION_IN:
636 *device_io_direction = SOUND_DEVICE_IO_DIRECTION_IN;
638 case MM_SOUND_DEVICE_IO_DIRECTION_OUT:
639 *device_io_direction = SOUND_DEVICE_IO_DIRECTION_OUT;
641 case MM_SOUND_DEVICE_IO_DIRECTION_BOTH:
642 *device_io_direction = SOUND_DEVICE_IO_DIRECTION_BOTH;
646 LOGI("device_io_direction[%d]", *device_io_direction);
648 return SOUND_MANAGER_ERROR_NONE;
651 const char* _convert_api_name(native_api_e api_name)
653 const char* name = NULL;
656 case NATIVE_API_SOUND_MANAGER:
657 name = "sound-manager";
659 case NATIVE_API_PLAYER:
662 case NATIVE_API_WAV_PLAYER:
665 case NATIVE_API_TONE_PLAYER:
666 name = "tone-player";
668 case NATIVE_API_AUDIO_IO:
671 case NATIVE_API_RECORDER:
679 int _convert_sample_format_enum_to_str(sound_sample_format_e format, char **format_str)
681 SM_ARG_CHECK(format_str);
684 case SOUND_SAMPLE_FORMAT_U8:
687 case SOUND_SAMPLE_FORMAT_S16_LE:
688 *format_str = "s16le";
690 case SOUND_SAMPLE_FORMAT_S24_LE:
691 *format_str = "s24le";
693 case SOUND_SAMPLE_FORMAT_S24_32_LE:
694 *format_str = "s24-32le";
697 LOGE("could not find format[%d] in this switch case statement", format);
698 return SOUND_MANAGER_ERROR_INTERNAL;
701 return SOUND_MANAGER_ERROR_NONE;
704 int _convert_sample_format_str_to_enum(const char *format_str, sound_sample_format_e *format)
706 SM_ARG_CHECK(format_str);
707 SM_ARG_CHECK(format);
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;
718 LOGE("not supported sample format(%s)", format_str);
719 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
722 LOGI("format[%s, %d]", format_str, *format);
724 return SOUND_MANAGER_ERROR_NONE;
727 int _convert_sample_rate_enum_to_uint(sound_sample_rate_e rate, unsigned int *sample_rate)
729 SM_ARG_CHECK(sample_rate);
732 case SOUND_SAMPLE_RATE_8000:
735 case SOUND_SAMPLE_RATE_16000:
736 *sample_rate = 16000;
738 case SOUND_SAMPLE_RATE_22050:
739 *sample_rate = 22050;
741 case SOUND_SAMPLE_RATE_44100:
742 *sample_rate = 44100;
744 case SOUND_SAMPLE_RATE_48000:
745 *sample_rate = 48000;
747 case SOUND_SAMPLE_RATE_88200:
748 *sample_rate = 88200;
750 case SOUND_SAMPLE_RATE_96000:
751 *sample_rate = 96000;
753 case SOUND_SAMPLE_RATE_192000:
754 *sample_rate = 192000;
757 LOGE("not supported sample rate(%u)", rate);
758 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
761 return SOUND_MANAGER_ERROR_NONE;
764 int _convert_sample_rate_to_enum(unsigned int rate, sound_sample_rate_e *rate_e)
766 SM_ARG_CHECK(rate_e);
770 *rate_e = SOUND_SAMPLE_RATE_8000;
773 *rate_e = SOUND_SAMPLE_RATE_16000;
776 *rate_e = SOUND_SAMPLE_RATE_22050;
779 *rate_e = SOUND_SAMPLE_RATE_44100;
782 *rate_e = SOUND_SAMPLE_RATE_48000;
785 *rate_e = SOUND_SAMPLE_RATE_88200;
788 *rate_e = SOUND_SAMPLE_RATE_96000;
791 *rate_e = SOUND_SAMPLE_RATE_192000;
794 LOGE("not supported sample rate(%u)", rate);
795 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
798 LOGI("rate[%d, %d]", rate, *rate_e);
800 return SOUND_MANAGER_ERROR_NONE;
804 int _return_val_if_not_usb_device(sound_device_h device, int ret_val)
806 mm_sound_device_type_e type;
808 if (mm_sound_get_device_type(device, &type))
811 if (type != MM_SOUND_DEVICE_TYPE_USB_AUDIO) {
812 LOGE("device type is not USB AUDIO");
816 return SOUND_MANAGER_ERROR_NONE;
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)
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;
829 LOGE("user_data is null");
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);
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);
844 SM_ENTER_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
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;
851 if (state == FOCUS_IS_ACQUIRED)
852 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
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);
859 if (state == FOCUS_IS_RELEASED)
860 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
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;
867 SM_LEAVE_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
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)
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;
884 LOGE("user_data is null");
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);
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);
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);
910 void _pa_context_state_cb(pa_context *c, void *userdata)
912 pa_context_state_t state;
913 sound_pa_info_s *pa_info = (sound_pa_info_s *)userdata;
916 LOGE("pa_context is null");
921 LOGE("pa_info is null");
925 state = pa_context_get_state(c);
927 LOGI("pa_info[%p] context state[%d]", pa_info, state);
929 if (state == PA_CONTEXT_FAILED) {
930 pa_info->is_disconnected = true;
931 LOGE("PA DISCONNECTED");
935 case PA_CONTEXT_READY:
936 case PA_CONTEXT_TERMINATED:
937 case PA_CONTEXT_FAILED:
938 pa_threaded_mainloop_signal(pa_info->mainloop, 0);
940 case PA_CONTEXT_UNCONNECTED:
941 case PA_CONTEXT_CONNECTING:
942 case PA_CONTEXT_AUTHORIZING:
943 case PA_CONTEXT_SETTING_NAME:
951 void _pa_stream_state_cb(pa_stream *s, void *userdata)
953 pa_stream_state_t state;
954 virtual_sound_stream_info_s *vstream_h = (virtual_sound_stream_info_s*)userdata;
957 LOGE("pa_stream is null");
962 LOGE("vstream_h is null");
966 state = pa_stream_get_state(s);
967 LOGI("vstream_h[%p] index[%d] state[%d]", vstream_h, pa_stream_get_index(s), 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);
975 case PA_STREAM_UNCONNECTED:
976 case PA_STREAM_CREATING:
984 int _get_stream_conf_info(const char *stream_type, stream_conf_info_s *info)
986 int ret = SOUND_MANAGER_ERROR_NONE;
987 GVariant *result = NULL;
988 GVariant *child = NULL;
989 GDBusConnection *conn = NULL;
992 GVariant *item = NULL;
997 SM_ARG_CHECK(stream_type);
1000 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1003 result = g_dbus_connection_call_sync(conn,
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,
1014 if (!result || err) {
1016 LOGE("g_dbus_connection_call_sync() for GET_STREAM_INFO error (%s)", err ? err->message : NULL);
1019 ret = SOUND_MANAGER_ERROR_INTERNAL;
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);
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);
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")))
1047 /* we use volume type only for out direction */
1049 LOGI(" volume-type : %s", name);
1050 info->volume_type = strdup(name);
1054 g_variant_unref(item);
1055 g_variant_unref(child);
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);
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);
1069 LOGI(" in-device name : %s", name);
1070 info->avail_in_devices[i++] = strdup(name);
1072 g_variant_unref(item);
1073 g_variant_unref(child);
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);
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);
1087 LOGI(" out-device name : %s", name);
1088 info->avail_out_devices[i++] = strdup(name);
1090 g_variant_unref(item);
1091 g_variant_unref(child);
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);
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
1105 LOGI(" framework name : %s", name);
1106 info->avail_frameworks[i++] = strdup(name);
1108 g_variant_unref(item);
1109 g_variant_unref(child);
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;
1118 g_variant_unref(result);
1119 g_object_unref(conn);
1124 int _set_manual_route_info(unsigned int index, manual_route_info_s *info)
1126 int ret = SOUND_MANAGER_ERROR_NONE;
1128 GVariantBuilder *builder_for_in_devices;
1129 GVariantBuilder *builder_for_out_devices;
1130 GVariant *result = NULL;
1131 GDBusConnection *conn = NULL;
1133 const gchar *dbus_ret = NULL;
1137 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1140 LOGI("index[%u]", index);
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;
1150 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1151 if (!info->route_in_devices[i])
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]);
1156 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1157 if (!info->route_out_devices[i])
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]);
1163 result = g_dbus_connection_call_sync(conn,
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,
1174 if (!result || err) {
1176 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_DEVICES error (%s)", err ? err->message : NULL);
1179 ret = SOUND_MANAGER_ERROR_INTERNAL;
1184 g_variant_get(result, "(&s)", &dbus_ret);
1186 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1187 ret = SOUND_MANAGER_ERROR_INTERNAL;
1189 info->is_set = true;
1191 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
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);
1206 int _set_route_option(unsigned int index, const char *name, int value)
1208 int ret = SOUND_MANAGER_ERROR_NONE;
1209 GVariant *result = NULL;
1210 GDBusConnection *conn = NULL;
1212 const gchar *dbus_ret = NULL;
1216 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1219 LOGI("index[%u] name[%s] value[%d]", index, name, value);
1221 result = g_dbus_connection_call_sync(conn,
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,
1232 if (!result || err) {
1233 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_OPTION error (%s)", err ? err->message : NULL);
1236 ret = SOUND_MANAGER_ERROR_INTERNAL;
1240 g_variant_get(result, "(&s)", &dbus_ret);
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;
1247 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1251 g_variant_unref(result);
1252 g_object_unref(conn);
1258 int _get_volume_max_level(const char *direction, const char *volume_type, unsigned int *max_level)
1260 int ret = SOUND_MANAGER_ERROR_NONE;
1261 GVariant *result = NULL;
1262 GDBusConnection *conn = NULL;
1264 const gchar *dbus_ret = NULL;
1266 SM_ARG_CHECK(direction);
1267 SM_ARG_CHECK(volume_type);
1268 SM_ARG_CHECK(max_level);
1270 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1273 result = g_dbus_connection_call_sync(conn,
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,
1284 if (!result || err) {
1286 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_MAX_LEVEL error (%s)", err ? err->message : NULL);
1289 ret = SOUND_MANAGER_ERROR_INTERNAL;
1294 g_variant_get(result, "(u&s)", max_level, &dbus_ret);
1296 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1297 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1299 LOGI("max_level[%u]", *max_level);
1301 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1305 g_variant_unref(result);
1306 g_object_unref(conn);
1312 int _get_volume_level(const char *direction, const char *volume_type, unsigned int *level)
1314 int ret = SOUND_MANAGER_ERROR_NONE;
1315 GVariant *result = NULL;
1316 GDBusConnection *conn = NULL;
1318 const gchar *dbus_ret = NULL;
1320 SM_ARG_CHECK(direction);
1321 SM_ARG_CHECK(volume_type);
1322 SM_ARG_CHECK(level);
1324 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1327 result = g_dbus_connection_call_sync(conn,
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,
1338 if (!result || err) {
1339 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1342 ret = SOUND_MANAGER_ERROR_INTERNAL;
1346 g_variant_get(result, "(u&s)", level, &dbus_ret);
1348 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1349 ret = SOUND_MANAGER_ERROR_INTERNAL;
1351 LOGI("level[%u]", *level);
1353 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1357 g_variant_unref(result);
1358 g_object_unref(conn);
1363 int _set_volume_level(const char *direction, const char *volume_type, unsigned int level)
1365 int ret = SOUND_MANAGER_ERROR_NONE;
1366 GVariant *result = NULL;
1367 GDBusConnection *conn = NULL;
1369 const gchar *dbus_ret = NULL;
1371 char volume_path[VCONF_PATH_MAX] = {0,};
1373 SM_ARG_CHECK(direction);
1374 SM_ARG_CHECK(volume_type);
1376 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1379 result = g_dbus_connection_call_sync(conn,
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,
1390 if (!result || err) {
1391 LOGE("g_dbus_connection_call_sync() for SET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1394 ret = SOUND_MANAGER_ERROR_INTERNAL;
1398 g_variant_get(result, "(&s)", &dbus_ret);
1400 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1401 ret = SOUND_MANAGER_ERROR_INTERNAL;
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);
1409 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1413 g_variant_unref(result);
1414 g_object_unref(conn);
1420 int _get_current_volume_type(const char *direction, char **volume_type)
1422 int ret = SOUND_MANAGER_ERROR_NONE;
1423 GVariant *result = NULL;
1424 GDBusConnection *conn = NULL;
1426 const gchar *dbus_volume_type = NULL;
1427 const gchar *dbus_ret = NULL;
1429 SM_ARG_CHECK(direction);
1430 SM_ARG_CHECK(volume_type);
1432 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1435 result = g_dbus_connection_call_sync(conn,
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,
1446 if (!result || err) {
1448 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_VOLUME_TYPE error (%s)", err ? err->message : NULL);
1451 ret = SOUND_MANAGER_ERROR_INTERNAL;
1456 g_variant_get(result, "(&s&s)", &dbus_volume_type, &dbus_ret);
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;
1465 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1468 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1472 g_variant_unref(result);
1473 g_object_unref(conn);
1478 int _get_current_media_routing_path(const char *direction, sound_device_type_e *device_type)
1480 int ret = SOUND_MANAGER_ERROR_NONE;
1481 GVariant *result = NULL;
1482 GDBusConnection *conn = NULL;
1484 const gchar *dbus_device_type = NULL;
1485 const gchar *dbus_ret = NULL;
1487 SM_ARG_CHECK(direction);
1488 SM_ARG_CHECK(device_type);
1490 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1493 result = g_dbus_connection_call_sync(conn,
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,
1504 if (!result || err) {
1506 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_MEDIA_ROUTING_PATH error (%s)", err ? err->message : NULL);
1509 ret = SOUND_MANAGER_ERROR_INTERNAL;
1514 g_variant_get(result, "(&s&s)", &dbus_device_type, &dbus_ret);
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
1520 if (!strncmp("none", dbus_device_type, strlen(dbus_device_type)))
1521 ret = SOUND_MANAGER_ERROR_NO_DATA;
1523 ret = SOUND_MANAGER_ERROR_INTERNAL;
1526 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1530 g_variant_unref(result);
1531 g_object_unref(conn);
1536 void _update_focus_status(unsigned int index, unsigned int acquired_focus_status)
1538 GVariant *result = NULL;
1539 GDBusConnection *conn = NULL;
1541 const gchar *dbus_ret = NULL;
1543 if (__get_dbus_connection(&conn))
1546 result = g_dbus_connection_call_sync(conn,
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,
1557 if (!result || err) {
1559 LOGE("g_dbus_connection_call_sync() for UPDATE_FOCUS_STATUS error (%s)", err ? err->message : NULL);
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
1572 g_variant_unref(result);
1573 g_object_unref(conn);
1577 int _is_device_running_by_id(int device_id, bool *is_running)
1579 int ret = SOUND_MANAGER_ERROR_NONE;
1580 GVariant *result = NULL;
1581 GDBusConnection *conn = NULL;
1583 gboolean _is_running;
1585 SM_ARG_CHECK(is_running);
1587 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1590 result = g_dbus_connection_call_sync(conn,
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,
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));
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");
1614 g_variant_unref(result);
1615 g_object_unref(conn);
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)
1623 int ret = SOUND_MANAGER_ERROR_NONE;
1624 GVariant *result = NULL;
1625 GDBusConnection *conn = NULL;
1627 GVariantIter *iter = NULL;
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, };
1634 SM_ARG_CHECK(formats);
1637 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1640 result = g_dbus_connection_call_sync(conn,
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,
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));
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;
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)
1670 sm_formats[elem_num - 1] = format;
1673 if (elem_num == 0) {
1674 LOGE("could not find supported sample formats");
1675 ret = SOUND_MANAGER_ERROR_INTERNAL;
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;
1684 memcpy(*formats, sm_formats, elem_num * sizeof(sound_sample_format_e));
1689 LOGI("num[%d]", *num);
1693 g_variant_iter_free(iter);
1695 g_variant_unref(result);
1696 g_object_unref(conn);
1701 int _set_sample_format(int device_id, sound_sample_format_e format)
1703 int ret = SOUND_MANAGER_ERROR_NONE;
1704 GDBusConnection *conn = NULL;
1705 GVariant *result = NULL;
1707 char *format_str = NULL;
1709 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1712 if ((ret = _convert_sample_format_enum_to_str(format, &format_str)) != SOUND_MANAGER_ERROR_NONE)
1715 result = g_dbus_connection_call_sync(conn,
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),
1722 G_DBUS_CALL_FLAGS_NONE,
1723 DBUS_METHOD_TIMEOUT,
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));
1733 g_variant_unref(result);
1735 g_object_unref(conn);
1740 int _get_sample_format(int device_id, sound_sample_format_e *format)
1742 int ret = SOUND_MANAGER_ERROR_NONE;
1743 GVariant *result = NULL;
1744 GDBusConnection *conn = NULL;
1747 sound_sample_format_e format_e;
1749 SM_ARG_CHECK(format);
1751 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1754 result = g_dbus_connection_call_sync(conn,
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,
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));
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)
1778 g_variant_unref(result);
1779 g_object_unref(conn);
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)
1787 int ret = SOUND_MANAGER_ERROR_NONE;
1788 GVariant *result = NULL;
1789 GDBusConnection *conn = NULL;
1791 GVariantIter *iter = NULL;
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, };
1798 SM_ARG_CHECK(rates);
1801 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1804 result = g_dbus_connection_call_sync(conn,
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,
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));
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;
1830 while (g_variant_iter_loop(iter, "u", &rate)) {
1831 if (_convert_sample_rate_to_enum(rate, &rate_e) != SOUND_MANAGER_ERROR_NONE)
1834 sm_rates[elem_num - 1] = rate_e;
1837 if (elem_num == 0) {
1838 LOGE("could not find supported sample rates");
1839 ret = SOUND_MANAGER_ERROR_INTERNAL;
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;
1848 memcpy(*rates, sm_rates, elem_num * sizeof(sound_sample_rate_e));
1853 LOGI("num[%d]", *num);
1857 g_variant_iter_free(iter);
1859 g_variant_unref(result);
1860 g_object_unref(conn);
1865 int _set_sample_rate(int device_id, sound_sample_rate_e rate)
1867 int ret = SOUND_MANAGER_ERROR_NONE;
1868 GDBusConnection *conn = NULL;
1869 GVariant *result = NULL;
1873 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1876 if ((ret = _convert_sample_rate_enum_to_uint(rate, &_rate)) != SOUND_MANAGER_ERROR_NONE)
1879 result = g_dbus_connection_call_sync(conn,
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),
1886 G_DBUS_CALL_FLAGS_NONE,
1887 DBUS_METHOD_TIMEOUT,
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));
1897 g_variant_unref(result);
1899 g_object_unref(conn);
1904 int _get_sample_rate(int device_id, sound_sample_rate_e *rate)
1906 int ret = SOUND_MANAGER_ERROR_NONE;
1907 GVariant *result = NULL;
1908 GDBusConnection *conn = NULL;
1911 sound_sample_rate_e rate_e;
1915 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1918 result = g_dbus_connection_call_sync(conn,
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,
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));
1936 g_variant_get(result, "(u)", &_rate);
1937 if ((ret = _convert_sample_rate_to_enum(_rate, &rate_e)) == SOUND_MANAGER_ERROR_NONE)
1942 g_variant_unref(result);
1943 g_object_unref(conn);
1948 int _set_avoid_resampling(int device_id, bool enable)
1950 int ret = SOUND_MANAGER_ERROR_NONE;
1951 GDBusConnection *conn = NULL;
1952 GVariant *result = NULL;
1955 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1958 result = g_dbus_connection_call_sync(conn,
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),
1965 G_DBUS_CALL_FLAGS_NONE,
1966 DBUS_METHOD_TIMEOUT,
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));
1976 g_variant_unref(result);
1978 g_object_unref(conn);
1983 int _get_avoid_resampling(int device_id, bool *enabled)
1985 int ret = SOUND_MANAGER_ERROR_NONE;
1986 GVariant *result = NULL;
1987 GDBusConnection *conn = NULL;
1991 SM_ARG_CHECK(enabled);
1993 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1996 result = g_dbus_connection_call_sync(conn,
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,
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));
2015 g_variant_get(result, "(b)", &_enabled);
2016 *enabled = (bool)_enabled;
2018 LOGI("enabled[%d]", *enabled);
2022 g_variant_unref(result);
2023 g_object_unref(conn);
2028 int _set_media_stream_only(int device_id, bool enable)
2030 int ret = SOUND_MANAGER_ERROR_NONE;
2031 GDBusConnection *conn = NULL;
2032 GVariant *result = NULL;
2034 const char *stream_type;
2036 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
2040 stream_type = STREAM_MEDIA;
2042 stream_type = "none";
2044 result = g_dbus_connection_call_sync(conn,
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),
2051 G_DBUS_CALL_FLAGS_NONE,
2052 DBUS_METHOD_TIMEOUT,
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));
2062 g_variant_unref(result);
2064 g_object_unref(conn);
2069 int _get_media_stream_only(int device_id, bool *enabled)
2071 int ret = SOUND_MANAGER_ERROR_NONE;
2072 GVariant *result = NULL;
2073 GDBusConnection *conn = NULL;
2077 SM_ARG_CHECK(enabled);
2079 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
2082 result = g_dbus_connection_call_sync(conn,
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,
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));
2101 g_variant_get(result, "(&s)", &stream_type);
2102 if (!strncmp(stream_type, STREAM_MEDIA, SOUND_STREAM_TYPE_LEN))
2107 LOGI("enabled[%d]", *enabled);
2111 g_variant_unref(result);
2112 g_object_unref(conn);
2118 int _make_pa_connection(sound_pa_info_s *pa_info, const char *context_name)
2122 SM_ARG_CHECK(pa_info);
2124 if (!(pa_info->mainloop = pa_threaded_mainloop_new()))
2127 if (!(pa_info->context = pa_context_new(pa_threaded_mainloop_get_api(pa_info->mainloop), context_name)))
2130 pa_context_set_state_callback(pa_info->context, _pa_context_state_cb, pa_info);
2132 if (pa_context_connect(pa_info->context, NULL, 0, NULL) < 0) {
2133 pa_ret = pa_context_errno(pa_info->context);//LCOV_EXCL_LINE
2137 pa_threaded_mainloop_lock(pa_info->mainloop);
2139 if (pa_threaded_mainloop_start(pa_info->mainloop) < 0)
2140 goto PA_ERROR_WITH_UNLOCK;
2142 /* wait for ready state of the context */
2144 pa_context_state_t state;
2145 state = pa_context_get_state(pa_info->context);
2146 if (state == PA_CONTEXT_READY)
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;
2152 pa_threaded_mainloop_wait(pa_info->mainloop);
2155 /* get index of this context */
2156 pa_info->index = pa_context_get_index(pa_info->context);
2158 pa_threaded_mainloop_unlock(pa_info->mainloop);
2160 return SOUND_MANAGER_ERROR_NONE;
2162 PA_ERROR_WITH_UNLOCK:
2163 pa_threaded_mainloop_unlock(pa_info->mainloop);
2166 _destroy_pa_connection(pa_info);
2167 LOGE("pa_ret %d", pa_ret);
2169 return SOUND_MANAGER_ERROR_INTERNAL;
2173 int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_stream_focus_state_changed_cb callback, void *user_data)
2175 int ret = SOUND_MANAGER_ERROR_NONE;
2176 int mm_ret = MM_ERROR_NONE;
2178 bool is_focus_cb_thread = false;
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);
2183 if (is_focus_cb_thread)
2184 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
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)
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);
2193 if ((ret = _make_pa_connection(&stream_h->pa_info, "SOUND_MANAGER_STREAM_INFO")) != SOUND_MANAGER_ERROR_NONE)
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;
2203 LOGE("failed to register focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2204 ret = _convert_sound_manager_error_code(__func__, mm_ret);
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]);
2215 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2216 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2218 SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2220 _destroy_pa_connection(&stream_h->pa_info);
2226 void _destroy_pa_connection(sound_pa_info_s *pa_info)
2229 LOGW("NULL pa info - skip..");
2233 LOGI("[%p][%p]", pa_info->mainloop, pa_info->context);
2235 if (pa_info->mainloop)
2236 pa_threaded_mainloop_stop(pa_info->mainloop);
2238 if (pa_info->context) {
2239 pa_context_disconnect(pa_info->context);
2240 pa_context_unref(pa_info->context);
2241 pa_info->context = NULL;
2244 if (pa_info->mainloop) {
2245 pa_threaded_mainloop_free(pa_info->mainloop);
2246 pa_info->mainloop = NULL;
2250 int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h)
2253 int ret = SOUND_MANAGER_ERROR_NONE;
2254 int mm_ret = MM_ERROR_NONE;
2255 bool is_focus_cb_thread = false;
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);
2260 if (is_focus_cb_thread)
2261 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2263 _destroy_pa_connection(&stream_h->pa_info);
2265 /* unregister focus */
2266 if (!stream_h->is_focus_unavailable) {
2267 mm_ret = mm_sound_unregister_focus(stream_h->focus_id);
2269 LOGE("failed to unregister focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2270 ret = _convert_sound_manager_error_code(__func__, mm_ret);
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]);
2278 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2279 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2281 SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2286 static int __dbus_method_call(const char *method, GVariant *param, GVariant **reply)
2288 GDBusConnection *conn = NULL;
2289 GVariant *_reply = NULL;
2293 if (!method || !param) {
2294 LOGE("invalid parameter");
2295 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
2299 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE) {
2300 ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
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);
2309 g_object_unref(conn);
2312 ret = _convert_dbus_error(err->message);
2313 LOGE("g_dbus_connection_call_sync() method(%s), err-msg(%s)", method, err->message);
2321 g_variant_unref(_reply);
2323 return SOUND_MANAGER_ERROR_NONE;
2327 g_variant_unref(param);
2333 static struct _publish_info {
2334 GDBusConnection *conn;
2337 sound_manager_remote_client_connected_cb cb;
2342 #define REMOTE_CLIENT_BIT_TYPE_MASK 0x80000000
2343 #define REMOTE_CLIENT_BIT_TYPE 31
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)
2349 struct _cb_info *cb_info = (struct _cb_info *)userdata;
2351 if (cb_info && cb_info->cb) {
2354 gboolean is_connected;
2355 gchar *name, *description;
2357 g_variant_get(params, "(iub&s&s)", &type, &id, &is_connected, &name, &description);
2359 LOGE("type(%d), id(%u), is_connected(%d), name(%s), description(%s)",
2360 type, id, is_connected, name, description);
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);
2368 static int __subscribe_remote_devices(sound_manager_remote_client_connected_cb callback, void *userdata)
2371 struct _cb_info *cb_info = &(publish_info.cb_info);
2373 if (publish_info.subs_id > 0) {
2374 LOGE("already subscribed remote device");
2375 return SOUND_MANAGER_ERROR_INTERNAL;
2378 if ((ret = __get_dbus_connection(&publish_info.conn)) != SOUND_MANAGER_ERROR_NONE)
2381 cb_info->cb = callback;
2382 cb_info->userdata = userdata;
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;
2395 LOGI("subscribe remote devices. subs_id %d", publish_info.subs_id);
2397 return SOUND_MANAGER_ERROR_NONE;
2400 static int __unsubscribe_remote_devices(void)
2404 if (publish_info.subs_id == 0) {
2405 LOGE("invalid subs_id(%d)", publish_info.subs_id);
2406 return SOUND_MANAGER_ERROR_INTERNAL;
2409 if ((ret = __get_dbus_connection(&publish_info.conn)) != SOUND_MANAGER_ERROR_NONE)
2412 g_dbus_connection_signal_unsubscribe(publish_info.conn, publish_info.subs_id);
2414 if (publish_info.conn) {
2415 g_object_unref(publish_info.conn);
2416 publish_info.conn = NULL;
2419 publish_info.subs_id = 0;
2421 LOGI("unsubscribe remote devices state subs_id %d", publish_info.subs_id);
2423 return SOUND_MANAGER_ERROR_NONE;
2426 int _publish_local_device(sound_manager_remote_client_connected_cb callback, void *user_data)
2430 LOGI("publish local device callback(%p), userdata(%p)", callback, user_data);
2432 ret = __subscribe_remote_devices(callback, user_data);
2433 if (ret != SOUND_MANAGER_ERROR_NONE) {
2434 LOGE("subscribe failed");
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");
2443 LOGE("publish local device failed");
2451 int _unpublish_local_device(void)
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");
2461 ret = __unsubscribe_remote_devices();
2462 if (ret != SOUND_MANAGER_ERROR_NONE) {
2463 LOGE("unsubscribe failed");
2470 int _discover_remote_device(bool enable)
2472 return __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_DISCOVER_REMOTE_DEVICE,
2473 g_variant_new("(b)", (gboolean)enable), NULL);
2476 int _set_remote_permission(int id, bool allowed)
2479 int index = (id << 1) >> 1;
2480 char *type = id & REMOTE_CLIENT_BIT_TYPE_MASK ? "source-output" : "sink-input";
2482 LOGI("id(%d), allowed(%d), index(%d), type(%s)", id, allowed, index, type);
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");
2492 int _start_aec(void)
2494 GDBusConnection *conn = NULL;
2495 GVariant *reply = NULL;
2499 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
2500 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2502 LOGI("start acoustic echo cancellation");
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);
2507 g_object_unref(conn);
2510 ret = _convert_dbus_error(err->message);
2511 LOGE("g_dbus_connection_call_sync() err-msg(%s)", err->message);
2516 g_variant_unref(reply);
2518 return SOUND_MANAGER_ERROR_NONE;
2524 GDBusConnection *conn = NULL;
2525 GVariant *reply = NULL;
2529 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
2530 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2532 LOGI("stop acoustic echo cancellation");
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);
2537 g_object_unref(conn);
2540 ret = _convert_dbus_error(err->message);
2541 LOGE("g_dbus_connection_call_sync() err-msg(%s)", err->message);
2546 g_variant_unref(reply);
2548 return SOUND_MANAGER_ERROR_NONE;
2551 static int __check_manual_route_type(sound_stream_info_s *stream_info)
2553 SM_ARG_CHECK(stream_info);
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;
2561 return SOUND_MANAGER_ERROR_NONE;
2564 static int __check_auto_route_type(sound_stream_info_s *stream_info)
2566 SM_ARG_CHECK(stream_info);
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;
2574 return SOUND_MANAGER_ERROR_NONE;
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)
2580 bool added_successfully = false;
2582 SM_ARG_CHECK(stream_info);
2583 SM_ARG_CHECK(device_type_str);
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])
2589 if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
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;
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;
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])
2609 if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
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;
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;
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;
2631 return SOUND_MANAGER_ERROR_NONE;
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)
2637 bool removed_successfully = false;
2639 SM_ARG_CHECK(stream_info);
2640 SM_ARG_CHECK(device_type_str);
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])
2646 if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
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;
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])
2662 if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
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;
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;
2680 return SOUND_MANAGER_ERROR_NONE;
2683 static int __is_available_device(sound_stream_info_s *stream_info, sound_device_h device, bool *available)
2685 int ret = SOUND_MANAGER_ERROR_NONE;
2686 int mm_ret = MM_ERROR_NONE;
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;
2695 SM_ARG_CHECK(stream_info);
2696 SM_ARG_CHECK(device);
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)
2702 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
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);
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]))
2711 if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2715 LOGE("[OUT] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2717 return SOUND_MANAGER_ERROR_NONE;
2721 if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_IN) {
2723 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2724 if (!(avail_device_item = stream_info->stream_conf_info.avail_in_devices[i]))
2726 if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2730 LOGE("[IN] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2732 return SOUND_MANAGER_ERROR_NONE;
2738 return SOUND_MANAGER_ERROR_NONE;
2741 int _add_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2743 int ret = SOUND_MANAGER_ERROR_NONE;
2744 int mm_ret = MM_ERROR_NONE;
2745 char *device_type_str = NULL;
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;
2751 SM_ARG_CHECK(stream_info);
2752 SM_ARG_CHECK(device);
2754 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
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)
2763 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
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);
2768 if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2771 LOGI("*** added device[type:%s, id:%d]", device_type_str, device_id);
2773 return SOUND_MANAGER_ERROR_NONE;
2776 int _remove_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2778 int ret = SOUND_MANAGER_ERROR_NONE;
2779 int mm_ret = MM_ERROR_NONE;
2780 char *device_type_str = NULL;
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;
2786 SM_ARG_CHECK(stream_info);
2787 SM_ARG_CHECK(device);
2789 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
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)
2798 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
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);
2803 if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2806 LOGI("*** removed device[type:%s, id:%d]", device_type_str, device_id);
2808 return SOUND_MANAGER_ERROR_NONE;
2811 int _remove_all_devices_for_stream_routing(sound_stream_info_s *stream_info)
2813 int ret = SOUND_MANAGER_ERROR_NONE;
2816 SM_ARG_CHECK(stream_info);
2818 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
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;
2826 stream_info->manual_route_info.is_set = false;
2828 LOGI("*** removed all devices");
2830 return SOUND_MANAGER_ERROR_NONE;
2833 int _add_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
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;
2843 SM_ARG_CHECK(stream_info);
2845 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
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);
2854 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)) != SOUND_MANAGER_ERROR_NONE)
2856 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
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);
2863 if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2866 LOGI("*** added device by id[type:%s, id:%d]", device_type_str, device_id);
2870 mm_sound_free_device(device);
2874 int _remove_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
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;
2884 SM_ARG_CHECK(stream_info);
2886 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
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);
2895 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)) != SOUND_MANAGER_ERROR_NONE)
2897 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
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);
2904 if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2907 LOGI("*** removed device by id[type:%s, id:%d]", device_type_str, device_id);
2911 mm_sound_free_device(device);
2915 int _apply_stream_routing(sound_stream_info_s *stream_info)
2919 SM_ARG_CHECK(stream_info);
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
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);
2935 return SOUND_MANAGER_ERROR_INVALID_STATE;
2939 int _create_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream)
2941 bool result = false;
2942 const char *name = NULL;
2945 SM_ARG_CHECK(stream_info);
2946 SM_ARG_CHECK(virtual_stream);
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))) {
2956 LOGI("stream_type[%s], native api[%s], is_available[%d]", stream_info->stream_type, name, result);
2958 return SOUND_MANAGER_ERROR_NOT_SUPPORTED;
2960 (*virtual_stream) = malloc(sizeof(virtual_sound_stream_info_s));
2961 if (!(*virtual_stream))
2962 return SOUND_MANAGER_ERROR_INTERNAL;
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;
2974 return SOUND_MANAGER_ERROR_NONE;
2977 int _destroy_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2979 SM_ARG_CHECK(virtual_stream);
2980 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_READY);
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);
2987 virtual_stream->stream_info->vstream = NULL;
2989 SM_SAFE_FREE(virtual_stream);
2991 return SOUND_MANAGER_ERROR_NONE;
2994 int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2996 int ret = SOUND_MANAGER_ERROR_NONE;
2999 int io_direction = 0;
3001 pa_channel_map maps;
3003 SM_ARG_CHECK(virtual_stream);
3004 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_READY);
3006 /* fill up with default value */
3009 ss.format = PA_SAMPLE_S16LE;
3010 pa_channel_map_init_auto(&maps, ss.channels, PA_CHANNEL_MAP_ALSA);
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;
3018 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
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;
3029 pa_stream_set_state_callback(virtual_stream->pa_stream[i], _pa_stream_state_cb, virtual_stream);
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);
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;
3039 } else if ((i + 1) == SOUND_STREAM_DIRECTION_INPUT) {
3040 pa_ret = pa_stream_connect_record(virtual_stream->pa_stream[i], NULL, NULL, 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;
3049 /* wait for ready state of the stream */
3051 pa_stream_state_t state;
3052 state = pa_stream_get_state(virtual_stream->pa_stream[i]);
3053 if (state == PA_STREAM_READY)
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;
3062 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
3066 virtual_stream->state = _VSTREAM_STATE_RUNNING;
3068 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
3070 return SOUND_MANAGER_ERROR_NONE;
3073 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
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;
3081 LOGE("pa_ret(%d)", pa_ret);
3085 int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
3089 SM_ARG_CHECK(virtual_stream);
3090 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_RUNNING);
3092 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
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]);
3098 /* wait for terminated state of the stream */
3100 pa_stream_state_t state;
3101 state = pa_stream_get_state(virtual_stream->pa_stream[i]);
3102 if (state == PA_STREAM_TERMINATED)
3104 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
3107 pa_stream_unref(virtual_stream->pa_stream[i]);
3108 virtual_stream->pa_stream[i] = NULL;
3112 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
3114 virtual_stream->state = _VSTREAM_STATE_READY;
3116 return SOUND_MANAGER_ERROR_NONE;
3119 int _set_volume_ratio(uint32_t stream_index, sound_stream_direction_e direction, double ratio)
3121 int ret = SOUND_MANAGER_ERROR_NONE;
3122 GDBusConnection *conn = NULL;
3124 GVariant *result = NULL;
3125 const gchar *dbus_ret = NULL;
3127 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3130 result = g_dbus_connection_call_sync(conn,
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,
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));
3149 g_variant_get(result, "(&s)", &dbus_ret);
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;
3158 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3162 g_variant_unref(result);
3163 g_object_unref(conn);
3168 int _set_virtual_stream_volume(virtual_sound_stream_info_s *virtual_stream, double ratio)
3170 int ret = SOUND_MANAGER_ERROR_NONE;
3174 SM_ARG_CHECK(virtual_stream);
3175 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_RUNNING);
3177 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
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;
3192 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
3197 int _set_acm_master_mode(bool on)
3199 int ret = SOUND_MANAGER_ERROR_NONE;
3200 GVariant *result = NULL;
3201 GDBusConnection *conn = NULL;
3204 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3207 result = g_dbus_connection_call_sync(conn,
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),
3214 G_DBUS_CALL_FLAGS_NONE,
3215 DBUS_METHOD_TIMEOUT,
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));
3224 LOGI("ACM master mode [%s]", on ? "ON" : "OFF");
3229 g_variant_unref(result);
3230 g_object_unref(conn);
3235 int _activate_ducking(uint32_t stream_index, bool enable, const char *target_stream, uint32_t duration, double ratio)
3237 int ret = SOUND_MANAGER_ERROR_NONE;
3238 GDBusConnection *conn = NULL;
3240 GVariant *result = NULL;
3241 const gchar *dbus_ret = NULL;
3243 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3246 result = g_dbus_connection_call_sync(conn,
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,
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));
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;
3271 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3275 g_variant_unref(result);
3276 g_object_unref(conn);
3281 int _get_ducking_state(sound_pa_info_s *pa_info, bool *is_ducked)
3283 int ret = SOUND_MANAGER_ERROR_NONE;
3284 gboolean _is_ducked = FALSE;
3285 GDBusConnection *conn = NULL;
3287 GVariant *result = NULL;
3288 const gchar *dbus_ret = NULL;
3290 SM_ARG_CHECK(pa_info);
3291 SM_ARG_CHECK(is_ducked);
3293 if (pa_info->is_disconnected) {
3294 LOGE("server disconnected");
3295 return SOUND_MANAGER_ERROR_INTERNAL;
3298 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3301 result = g_dbus_connection_call_sync(conn,
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,
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));
3320 g_variant_get(result, "(b&s)", &_is_ducked, &dbus_ret);
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);
3326 ret = SOUND_MANAGER_ERROR_INTERNAL;
3329 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3333 g_variant_unref(result);
3334 g_object_unref(conn);
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)
3341 int ret = SOUND_MANAGER_ERROR_NONE;
3342 GVariant *result = NULL;
3343 GDBusConnection *conn = NULL;
3345 const gchar *dbus_ret = NULL;
3346 const gchar *direction_str;
3349 SM_ARG_CHECK(stream_info);
3351 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3354 for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
3356 if (!(io_direction & (i + 1)))
3359 if (!((req_direction + 1) & (i + 1)))
3362 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3364 result = g_dbus_connection_call_sync(conn,
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),
3371 G_DBUS_CALL_FLAGS_NONE,
3372 DBUS_METHOD_TIMEOUT,
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));
3383 LOGI("Preferred device(id:%d, direction:%s) is set to PA context(%u)", device_id, direction_str, stream_info->pa_info.index);
3385 g_variant_get(result, "(&s)", &dbus_ret);
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;
3394 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3399 if (i == SOUND_DEVICE_IO_DIRECTION_IN)
3400 stream_info->preferred_device_info.in = device_id;
3402 stream_info->preferred_device_info.out = device_id;
3407 g_variant_unref(result);
3408 g_object_unref(conn);
3413 int _set_preferred_device(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, sound_device_h device)
3415 int ret = SOUND_MANAGER_ERROR_NONE;
3416 int mm_ret = MM_ERROR_NONE;
3417 bool available = false;
3419 mm_sound_device_io_direction_e io_direction = MM_SOUND_DEVICE_IO_DIRECTION_IN;
3421 SM_ARG_CHECK(stream_info);
3423 /* allow only auto route type */
3424 if ((ret = __check_auto_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
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. */
3430 if ((ret = __is_available_device(stream_info, device, &available)) != SOUND_MANAGER_ERROR_NONE)
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;
3444 return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3447 int _set_preferred_device_id(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, int device_id)
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;
3454 SM_ARG_CHECK(stream_info);
3456 /* allow only auto route type */
3457 if ((ret = __check_auto_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
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. */
3463 MMSoundDevice_t device = NULL;
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);
3469 if ((ret = __is_available_device(stream_info, (sound_device_h)device, &available)) != SOUND_MANAGER_ERROR_NONE)
3472 ret = SOUND_MANAGER_ERROR_POLICY;
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);
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;
3484 mm_sound_free_device(device);
3489 return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3492 int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id)
3494 int ret = SOUND_MANAGER_ERROR_NONE;
3495 GDBusConnection *conn = NULL;
3497 GVariant *result = NULL;
3498 const gchar *dbus_ret = NULL;
3499 unsigned int _in_device_id;
3500 unsigned int _out_device_id;
3502 SM_ARG_CHECK(stream_info);
3504 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3507 result = g_dbus_connection_call_sync(conn,
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,
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));
3526 g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3528 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
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;
3534 *in_device_id = _in_device_id;
3535 LOGI("preferred device id[in:%d]", *in_device_id);
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;
3543 *out_device_id = _out_device_id;
3544 LOGI("preferred device id[out:%d]", *out_device_id);
3548 ret = SOUND_MANAGER_ERROR_INTERNAL;
3551 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3555 g_variant_unref(result);
3556 g_object_unref(conn);
3561 static int __invoke_ipc_set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e io_direction, int device_id)
3563 int ret = SOUND_MANAGER_ERROR_NONE;
3564 GVariant *result = NULL;
3565 GDBusConnection *conn = NULL;
3567 const gchar *dbus_ret = NULL;
3568 const gchar *direction_str;
3569 char *stream_type_str;
3572 if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != SOUND_MANAGER_ERROR_NONE)
3575 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
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)
3581 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3583 result = g_dbus_connection_call_sync(conn,
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),
3590 G_DBUS_CALL_FLAGS_NONE,
3591 DBUS_METHOD_TIMEOUT,
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));
3601 g_variant_unref(result);
3607 LOGI("Preemptive device(id:%d, direction:%s) is set", device_id, direction_str);
3609 g_variant_get(result, "(&s)", &dbus_ret);
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;
3618 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3626 g_variant_unref(result);
3627 g_object_unref(conn);
3632 static int __invoke_ipc_get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3634 int ret = SOUND_MANAGER_ERROR_NONE;
3635 GDBusConnection *conn = 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;
3643 if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != SOUND_MANAGER_ERROR_NONE)
3646 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3649 result = g_dbus_connection_call_sync(conn,
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,
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));
3667 g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3669 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3671 *in_device_id = _in_device_id;
3672 LOGI("preemptive device id[in:%d]", *in_device_id);
3674 if (out_device_id) {
3675 *out_device_id = _out_device_id;
3676 LOGI("preemptive device id[out:%d]", *out_device_id);
3679 ret = SOUND_MANAGER_ERROR_INTERNAL;
3682 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3686 g_variant_unref(result);
3687 g_object_unref(conn);
3692 int _set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id)
3694 return __invoke_ipc_set_preemptive_device(stream_type, direction, device_id);
3697 int _get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3699 return __invoke_ipc_get_preemptive_device(stream_type, in_device_id, out_device_id);
3702 int _get_latest_stream_pid(int stream_type, unsigned int *pid)
3704 int ret = SOUND_MANAGER_ERROR_NONE;
3705 GDBusConnection *conn = NULL;
3707 GVariant *result = NULL;
3708 GVariantBuilder *builder_for_stream_types;
3709 const gchar *dbus_ret = NULL;
3714 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
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;
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);
3737 result = g_dbus_connection_call_sync(conn,
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,
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));
3756 g_variant_get(result, "(u&s)", &_pid, &dbus_ret);
3758 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3760 else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
3761 ret = SOUND_MANAGER_ERROR_NO_DATA;
3763 ret = SOUND_MANAGER_ERROR_INTERNAL;
3765 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3768 if (builder_for_stream_types)
3769 g_variant_builder_unref(builder_for_stream_types);
3771 g_variant_unref(result);
3772 g_object_unref(conn);