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"
71 #define PA_STREAM_MANAGER_METHOD_NAME_SET_RPI_PLAYBACK_ROUTE "SetRpiPlaybackRoute"
73 #define PA_STREAM_MANAGER_SIGNAL_NAME_REMOTE_FOUND "RemoteFound"
75 #define PA_DEVICE_MANAGER_OBJECT_PATH "/org/pulseaudio/DeviceManager"
76 #define PA_DEVICE_MANAGER_INTERFACE "org.pulseaudio.DeviceManager"
77 #define PA_DEVICE_MANAGER_METHOD_NAME_IS_DEVICE_RUNNING_BY_ID "IsDeviceRunningById"
78 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_FORMATS "GetSupportedSampleFormats"
79 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_FORMAT "SetSampleFormat"
80 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_FORMAT "GetSampleFormat"
81 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_RATES "GetSupportedSampleRates"
82 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_RATE "SetSampleRate"
83 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_RATE "GetSampleRate"
84 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_AVOID_RESAMPLING "SetAvoidResampling"
85 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_AVOID_RESAMPLING "GetAvoidResampling"
86 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SPECIFIC_STREAM "SetSpecificStreamOnly"
87 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SPECIFIED_STREAM "GetSpecifiedStream"
88 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_ACM_MODE "SetAcmMode"
90 #define VCONF_PATH_PREFIX_VOLUME "file/private/sound/volume/"
91 #define VCONF_PATH_MAX 64
93 #define VCONF_SOUND_RPI_PLAYBACK_ROUTE "file/private/sound/rpi_playback_route"
95 #define SM_SOUND_TYPE_CHECK(x_sound_type, x_error) \
96 if (!strncmp(x_sound_type, "system", strlen(x_sound_type)) || \
97 !strncmp(x_sound_type, "notification", strlen(x_sound_type)) || \
98 !strncmp(x_sound_type, "alarm", strlen(x_sound_type)) || \
99 !strncmp(x_sound_type, "ringtone", strlen(x_sound_type)) || \
100 !strncmp(x_sound_type, "media", strlen(x_sound_type)) || \
101 !strncmp(x_sound_type, "call", strlen(x_sound_type)) || \
102 !strncmp(x_sound_type, "voip", strlen(x_sound_type)) || \
103 !strncmp(x_sound_type, "voice", strlen(x_sound_type))) \
106 #define SM_INTERNAL_SOUND_TYPE_CHECK(x_sound_type, x_error) \
107 if (!strncmp(x_sound_type, "bixby", strlen(x_sound_type))) \
111 int _convert_dbus_error(const char *error_msg)
113 int ret = MM_ERROR_NONE;
116 return MM_ERROR_SOUND_INTERNAL;
118 if (strstr(error_msg, "InvalidArgument"))
119 ret = MM_ERROR_INVALID_ARGUMENT;
120 else if (strstr(error_msg, "InvalidOperation"))
121 ret = MM_ERROR_SOUND_INVALID_OPERATION;
122 else if (strstr(error_msg, "PolicyInternal"))
123 ret = MM_ERROR_POLICY_INTERNAL;
124 else if (strstr(error_msg, "AccessDenied"))
125 ret = MM_ERROR_SOUND_PERMISSION_DENIED;
127 ret = MM_ERROR_SOUND_INTERNAL;
129 LOGE("%s => 0x%x", error_msg, ret);
135 int _convert_sound_manager_error_code(const char *func, int code)
137 int ret = SOUND_MANAGER_ERROR_NONE;
138 char *errorstr = NULL;
141 case MM_ERROR_FILE_WRITE:
142 case MM_ERROR_INVALID_HANDLE:
143 case MM_ERROR_SOUND_INVALID_OPERATION:
144 ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
145 errorstr = "INVALID_OPERATION";
148 ret = SOUND_MANAGER_ERROR_NONE;
149 errorstr = "ERROR_NONE";
151 case MM_ERROR_INVALID_ARGUMENT:
152 case MM_ERROR_SOUND_INVALID_POINTER:
153 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
154 errorstr = "INVALID_PARAMETER";
156 case MM_ERROR_SOUND_PERMISSION_DENIED:
158 ret = SOUND_MANAGER_ERROR_PERMISSION_DENIED;
159 errorstr = "PERMISSION_DENIED";
162 case MM_ERROR_SOUND_NO_DATA:
163 ret = SOUND_MANAGER_ERROR_NO_DATA;
164 errorstr = "NO_DATA";
166 case MM_ERROR_SOUND_INTERNAL:
167 case MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY:
168 case MM_ERROR_OUT_OF_MEMORY:
169 case MM_ERROR_SOUND_SERVER_DISCONNECTED:
171 ret = SOUND_MANAGER_ERROR_INTERNAL;
172 errorstr = "INTERNAL";
175 case MM_ERROR_POLICY_DUPLICATED:
176 case MM_ERROR_POLICY_INTERNAL:
177 case MM_ERROR_POLICY_BLOCKED:
178 ret = SOUND_MANAGER_ERROR_POLICY;
181 case MM_ERROR_SOUND_VOLUME_NO_INSTANCE:
182 ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
183 errorstr = "NO_PLAYING_SOUND";
185 case MM_ERROR_NOT_SUPPORT_API:
186 ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
187 errorstr = "NOT_SUPPORTED";
189 case MM_ERROR_SOUND_INVALID_STATE:
190 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
191 errorstr = "INVALID_STATE";
195 LOGW("it should not be reached here, this error(0x%x) should be defined.", code);
196 ret = SOUND_MANAGER_ERROR_INTERNAL;
197 errorstr = "INTERNAL";
202 LOGE("[%s] >> leave : %s(0x%08x), mm_error(0x%08x)", func, errorstr, ret, code);
204 LOGD("[%s] >> leave : %s(0x%08x)", func, errorstr, ret);
209 int _convert_stream_type(sound_stream_type_e stream_type_enum, char **stream_type)
211 SM_ARG_CHECK(stream_type);
213 switch (stream_type_enum) {
214 case SOUND_STREAM_TYPE_MEDIA:
215 *stream_type = STREAM_MEDIA;
217 case SOUND_STREAM_TYPE_SYSTEM:
218 *stream_type = STREAM_SYSTEM;
220 case SOUND_STREAM_TYPE_ALARM:
221 *stream_type = STREAM_ALARM;
223 case SOUND_STREAM_TYPE_NOTIFICATION:
224 *stream_type = STREAM_NOTIFICATION;
226 case SOUND_STREAM_TYPE_EMERGENCY:
227 *stream_type = STREAM_EMERGENCY;
229 case SOUND_STREAM_TYPE_VOICE_INFORMATION:
230 *stream_type = STREAM_VOICE_INFORMATION;
232 case SOUND_STREAM_TYPE_VOICE_RECOGNITION:
233 *stream_type = STREAM_VOICE_RECOGNITION;
235 case SOUND_STREAM_TYPE_RINGTONE_VOIP:
236 *stream_type = STREAM_RINGTONE_VOIP;
238 case SOUND_STREAM_TYPE_VOIP:
239 *stream_type = STREAM_VOIP;
241 case SOUND_STREAM_TYPE_MEDIA_EXTERNAL_ONLY:
242 *stream_type = STREAM_EXT_MEDIA;
246 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
247 return SOUND_MANAGER_ERROR_INTERNAL;
251 LOGI("stream_type[%s]", *stream_type);
253 return SOUND_MANAGER_ERROR_NONE;
257 int _convert_stream_type_for_internal(sound_stream_type_internal_e stream_type_enum, char **stream_type)
259 SM_ARG_CHECK(stream_type);
261 switch (stream_type_enum) {
262 case SOUND_STREAM_TYPE_RINGTONE_CALL:
263 *stream_type = STREAM_RINGTONE_CALL;
265 case SOUND_STREAM_TYPE_RINGBACKTONE_CALL:
266 *stream_type = STREAM_RINGBACKTONE_CALL;
268 case SOUND_STREAM_TYPE_VOICE_CALL:
269 *stream_type = STREAM_CALL_VOICE;
271 case SOUND_STREAM_TYPE_VIDEO_CALL:
272 *stream_type = STREAM_CALL_VIDEO;
274 case SOUND_STREAM_TYPE_RADIO:
275 *stream_type = STREAM_RADIO;
277 case SOUND_STREAM_TYPE_LOOPBACK:
278 *stream_type = STREAM_LOOPBACK;
280 case SOUND_STREAM_TYPE_LOOPBACK_MIRRORING:
281 *stream_type = STREAM_LOOPBACK_MIRRORING;
283 case SOUND_STREAM_TYPE_SOLO:
284 *stream_type = STREAM_SOLO;
286 case SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE:
287 *stream_type = STREAM_VOICE_RECOGNITION_SERVICE;
289 case SOUND_STREAM_TYPE_MEDIA_COMPRESSED:
290 *stream_type = STREAM_COMPRESSED_MEDIA;
292 #ifndef TIZEN_FEATURE_TV_PROD
293 case SOUND_STREAM_TYPE_MEDIA_NETWORK_SOURCE:
294 *stream_type = STREAM_NETWORK_SOURCE_MEDIA;
298 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
299 return SOUND_MANAGER_ERROR_INTERNAL;
301 LOGI("stream_type_for_internal[%s]", *stream_type);
303 return SOUND_MANAGER_ERROR_NONE;
306 void _set_focus_availability(sound_stream_info_s *stream_info)
308 if (stream_info == NULL || stream_info->stream_type == NULL) {
309 LOGE("invalid argument");
312 if (!strncmp(stream_info->stream_type, STREAM_SOLO, SOUND_STREAM_TYPE_LEN) ||
313 !strncmp(stream_info->stream_type, STREAM_RADIO, SOUND_STREAM_TYPE_LEN) ||
314 !strncmp(stream_info->stream_type, STREAM_LOOPBACK_MIRRORING, SOUND_STREAM_TYPE_LEN)) {
315 stream_info->is_focus_unavailable = true;
316 LOGI("this stream_type[%s] does not support focus", stream_info->stream_type);
323 int _convert_stream_type_to_change_reason(const char *stream_type, sound_stream_focus_change_reason_e *change_reason)
325 SM_ARG_CHECK(stream_type);
326 SM_ARG_CHECK(change_reason);
328 if (!strncmp(stream_type, STREAM_MEDIA, SOUND_STREAM_TYPE_LEN) ||
329 !strncmp(stream_type, STREAM_COMPRESSED_MEDIA, SOUND_STREAM_TYPE_LEN) ||
330 !strncmp(stream_type, STREAM_RADIO, SOUND_STREAM_TYPE_LEN) ||
331 !strncmp(stream_type, STREAM_LOOPBACK, SOUND_STREAM_TYPE_LEN)) {
332 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
334 } else if (!strncmp(stream_type, STREAM_SYSTEM, SOUND_STREAM_TYPE_LEN)) {
335 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM;//LCOV_EXCL_LINE
337 } else if (!strncmp(stream_type, STREAM_ALARM, SOUND_STREAM_TYPE_LEN)) {
338 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_ALARM;
340 } else if (!strncmp(stream_type, STREAM_NOTIFICATION, SOUND_STREAM_TYPE_LEN)) {
341 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION;
343 } else if (!strncmp(stream_type, STREAM_EMERGENCY, SOUND_STREAM_TYPE_LEN)) {
344 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY;//LCOV_EXCL_LINE
346 } else if (!strncmp(stream_type, STREAM_VOICE_INFORMATION, SOUND_STREAM_TYPE_LEN)) {
347 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION;//LCOV_EXCL_LINE
349 } else if (!strncmp(stream_type, STREAM_VOICE_RECOGNITION, SOUND_STREAM_TYPE_LEN) ||
350 !strncmp(stream_type, STREAM_VOICE_RECOGNITION_SERVICE, SOUND_STREAM_TYPE_LEN)) {
351 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION;
353 } else if (!strncmp(stream_type, STREAM_RINGTONE_VOIP, SOUND_STREAM_TYPE_LEN) ||
354 !strncmp(stream_type, STREAM_RINGTONE_CALL, SOUND_STREAM_TYPE_LEN) ||
355 !strncmp(stream_type, STREAM_RINGBACKTONE_CALL, SOUND_STREAM_TYPE_LEN)) {
356 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE;
358 } else if (!strncmp(stream_type, STREAM_VOIP, SOUND_STREAM_TYPE_LEN)) {
359 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOIP;
361 } else if (!strncmp(stream_type, STREAM_CALL_VOICE, SOUND_STREAM_TYPE_LEN) ||
362 !strncmp(stream_type, STREAM_CALL_VIDEO, SOUND_STREAM_TYPE_LEN)) {
363 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_CALL;//LCOV_EXCL_LINE
365 } else if (!strncmp(stream_type, STREAM_EXT_MEDIA, SOUND_STREAM_TYPE_LEN)) {
366 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY;
370 LOGE("not supported stream_type(%s)", stream_type);
371 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
375 return SOUND_MANAGER_ERROR_NONE;
378 static int __get_dbus_connection(GDBusConnection **conn)
382 *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
383 if (!(*conn) || err) {
385 LOGE("g_bus_get_sync() error (%s)", err ? err->message : NULL);
388 return SOUND_MANAGER_ERROR_INTERNAL;
392 return SOUND_MANAGER_ERROR_NONE;
395 int _convert_sound_type(sound_type_e sound_type, const char **volume_type)
397 SM_ARG_CHECK(volume_type);
399 switch (sound_type) {
400 case SOUND_TYPE_SYSTEM:
401 *volume_type = "system";
403 case SOUND_TYPE_NOTIFICATION:
404 *volume_type = "notification";
406 case SOUND_TYPE_ALARM:
407 *volume_type = "alarm";
409 case SOUND_TYPE_RINGTONE:
410 *volume_type = "ringtone";
412 case SOUND_TYPE_MEDIA:
413 *volume_type = "media";
415 case SOUND_TYPE_CALL:
416 *volume_type = "call";
418 case SOUND_TYPE_VOIP:
419 *volume_type = "voip";
421 case SOUND_TYPE_VOICE:
422 *volume_type = "voice";
425 LOGI("volume_type[%s]", *volume_type);
427 return SOUND_MANAGER_ERROR_NONE;
431 int _convert_sound_type_for_internal(sound_type_internal_e sound_type, const char **volume_type)
433 SM_ARG_CHECK(volume_type);
435 switch (sound_type) {
436 case SOUND_TYPE_BIXBY:
437 *volume_type = "bixby";
440 LOGI("volume_type[%s]", *volume_type);
442 return SOUND_MANAGER_ERROR_NONE;
446 int _convert_sound_type_to_enum(const char *sound_type, sound_type_e *sound_type_enum)
448 SM_ARG_CHECK(sound_type);
449 SM_ARG_CHECK(sound_type_enum);
451 if (!strncmp(sound_type, "system", strlen(sound_type))) {
452 *sound_type_enum = SOUND_TYPE_SYSTEM;//LCOV_EXCL_LINE
453 } else if (!strncmp(sound_type, "notification", strlen(sound_type))) {
454 *sound_type_enum = SOUND_TYPE_NOTIFICATION;//LCOV_EXCL_LINE
455 } else if (!strncmp(sound_type, "alarm", strlen(sound_type))) {
456 *sound_type_enum = SOUND_TYPE_ALARM;
457 } else if (!strncmp(sound_type, "ringtone", strlen(sound_type))) {
458 *sound_type_enum = SOUND_TYPE_RINGTONE;//LCOV_EXCL_LINE
459 } else if (!strncmp(sound_type, "media", strlen(sound_type))) {
460 *sound_type_enum = SOUND_TYPE_MEDIA;
461 } else if (!strncmp(sound_type, "call", strlen(sound_type))) {
462 *sound_type_enum = SOUND_TYPE_CALL;//LCOV_EXCL_LINE
463 } else if (!strncmp(sound_type, "voip", strlen(sound_type))) {
464 *sound_type_enum = SOUND_TYPE_VOIP;
465 } else if (!strncmp(sound_type, "voice", strlen(sound_type))) {
466 *sound_type_enum = SOUND_TYPE_VOICE;
469 SM_INTERNAL_SOUND_TYPE_CHECK(sound_type, SOUND_MANAGER_ERROR_NO_PLAYING_SOUND);
470 LOGE("not supported sound_type(%s)", sound_type);
471 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
475 return SOUND_MANAGER_ERROR_NONE;
478 int _convert_sound_type_to_enum_for_internal(const char *sound_type, sound_type_internal_e *sound_type_enum)
480 SM_ARG_CHECK(sound_type);
481 SM_ARG_CHECK(sound_type_enum);
483 if (!strncmp(sound_type, "bixby", strlen(sound_type))) {
484 *sound_type_enum = SOUND_TYPE_BIXBY;
486 SM_SOUND_TYPE_CHECK(sound_type, SOUND_MANAGER_ERROR_NO_PLAYING_SOUND);
487 LOGE("not supported internal sound_type(%s)", sound_type);
488 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
491 return SOUND_MANAGER_ERROR_NONE;
494 int _convert_device_type_enum_to_str(sound_device_type_e device_type, char **device_type_str)
496 SM_ARG_CHECK(device_type_str);
498 switch (device_type) {
499 case SOUND_DEVICE_BUILTIN_SPEAKER:
500 *device_type_str = "builtin-speaker";
502 case SOUND_DEVICE_BUILTIN_RECEIVER:
503 *device_type_str = "builtin-receiver";
505 case SOUND_DEVICE_BUILTIN_MIC:
506 *device_type_str = "builtin-mic";
508 case SOUND_DEVICE_AUDIO_JACK:
509 *device_type_str = "audio-jack";
511 case SOUND_DEVICE_BLUETOOTH_MEDIA:
512 *device_type_str = "bt-a2dp";
514 case SOUND_DEVICE_BLUETOOTH_VOICE:
515 *device_type_str = "bt-sco";
517 case SOUND_DEVICE_HDMI:
518 *device_type_str = "hdmi";
520 case SOUND_DEVICE_USB_AUDIO:
521 *device_type_str = "usb-audio";
523 case SOUND_DEVICE_FORWARDING:
524 *device_type_str = "forwarding";
526 case SOUND_DEVICE_NETWORK:
527 *device_type_str = "network";
530 LOGE("could not find the device_type[%d] in this switch case statement", device_type);
531 return SOUND_MANAGER_ERROR_INTERNAL;
534 LOGI("device_type[%s]", *device_type_str);
536 return SOUND_MANAGER_ERROR_NONE;
539 int _convert_device_type_str_to_enum(const char *device_type_str, sound_device_type_e *device_type)
541 SM_ARG_CHECK(device_type_str);
542 SM_ARG_CHECK(device_type);
544 if (!strncmp(device_type_str, "builtin-speaker", SOUND_DEVICE_TYPE_LEN)) {
545 *device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
547 } else if (!strncmp(device_type_str, "builtin-receiver", SOUND_DEVICE_TYPE_LEN)) {
548 *device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
550 } else if (!strncmp(device_type_str, "builtin-mic", SOUND_DEVICE_TYPE_LEN)) {
551 *device_type = SOUND_DEVICE_BUILTIN_MIC;
553 } else if (!strncmp(device_type_str, "audio-jack", SOUND_DEVICE_TYPE_LEN)) {
554 *device_type = SOUND_DEVICE_AUDIO_JACK;
555 } else if (!strncmp(device_type_str, "hdmi", SOUND_DEVICE_TYPE_LEN)) {
556 *device_type = SOUND_DEVICE_HDMI;
558 } else if (!strncmp(device_type_str, "usb-audio", SOUND_DEVICE_TYPE_LEN)) {
559 *device_type = SOUND_DEVICE_USB_AUDIO;
561 } else if (!strncmp(device_type_str, "bt-a2dp", SOUND_DEVICE_TYPE_LEN)) {
562 *device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
564 } else if (!strncmp(device_type_str, "bt-sco", SOUND_DEVICE_TYPE_LEN)) {
565 *device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
567 } else if (!strncmp(device_type_str, "network", SOUND_DEVICE_TYPE_LEN)) {
568 *device_type = SOUND_DEVICE_NETWORK;
571 LOGE("not supported device_type(%s)", device_type_str);
572 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
575 LOGI("device_type[%s, %d]", device_type_str, *device_type);
577 return SOUND_MANAGER_ERROR_NONE;
580 int _convert_device_type(mm_sound_device_type_e device_type, sound_device_type_e *sound_device_type)
582 SM_ARG_CHECK(sound_device_type);
584 switch (device_type) {
585 case MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER:
586 *sound_device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
588 case MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER:
589 *sound_device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
591 case MM_SOUND_DEVICE_TYPE_BUILTIN_MIC:
592 *sound_device_type = SOUND_DEVICE_BUILTIN_MIC;
595 case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
596 *sound_device_type = SOUND_DEVICE_AUDIO_JACK;
598 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP:
599 *sound_device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
601 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_SCO:
602 *sound_device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
604 case MM_SOUND_DEVICE_TYPE_HDMI:
605 *sound_device_type = SOUND_DEVICE_HDMI;
607 case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
608 *sound_device_type = SOUND_DEVICE_USB_AUDIO;
610 case MM_SOUND_DEVICE_TYPE_MIRRORING:
611 *sound_device_type = SOUND_DEVICE_FORWARDING;
613 case MM_SOUND_DEVICE_TYPE_NETWORK:
614 *sound_device_type = SOUND_DEVICE_NETWORK;
617 LOGE("not supported device_type(%d)", device_type);
618 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
622 LOGI("device_type[%d]", *sound_device_type);
624 return SOUND_MANAGER_ERROR_NONE;
627 int _convert_device_io_direction(mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *device_io_direction)
629 SM_ARG_CHECK(device_io_direction);
631 switch (io_direction) {
632 case MM_SOUND_DEVICE_IO_DIRECTION_IN:
633 *device_io_direction = SOUND_DEVICE_IO_DIRECTION_IN;
635 case MM_SOUND_DEVICE_IO_DIRECTION_OUT:
636 *device_io_direction = SOUND_DEVICE_IO_DIRECTION_OUT;
638 case MM_SOUND_DEVICE_IO_DIRECTION_BOTH:
639 *device_io_direction = SOUND_DEVICE_IO_DIRECTION_BOTH;
643 LOGI("device_io_direction[%d]", *device_io_direction);
645 return SOUND_MANAGER_ERROR_NONE;
648 const char* _convert_api_name(native_api_e api_name)
651 case NATIVE_API_SOUND_MANAGER:
652 return "sound-manager";
653 case NATIVE_API_PLAYER:
655 case NATIVE_API_WAV_PLAYER:
657 case NATIVE_API_TONE_PLAYER:
658 return "tone-player";
659 case NATIVE_API_AUDIO_IO:
661 case NATIVE_API_RECORDER:
663 case NATIVE_API_WEBRTC:
670 int _convert_sample_format_enum_to_str(sound_sample_format_e format, char **format_str)
672 SM_ARG_CHECK(format_str);
675 case SOUND_SAMPLE_FORMAT_U8:
678 case SOUND_SAMPLE_FORMAT_S16_LE:
679 *format_str = "s16le";
681 case SOUND_SAMPLE_FORMAT_S24_LE:
682 *format_str = "s24le";
684 case SOUND_SAMPLE_FORMAT_S24_32_LE:
685 *format_str = "s24-32le";
688 LOGE("could not find format[%d] in this switch case statement", format);
689 return SOUND_MANAGER_ERROR_INTERNAL;
692 return SOUND_MANAGER_ERROR_NONE;
695 int _convert_sample_format_str_to_enum(const char *format_str, sound_sample_format_e *format)
697 SM_ARG_CHECK(format_str);
698 SM_ARG_CHECK(format);
700 if (!strncmp(format_str, "u8", SOUND_SAMPLE_FORMAT_LEN) || !strncmp(format_str, "8", SOUND_SAMPLE_FORMAT_LEN)) {
701 *format = SOUND_SAMPLE_FORMAT_U8;
702 } else if (!strncmp(format_str, "s16le", SOUND_SAMPLE_FORMAT_LEN)) {
703 *format = SOUND_SAMPLE_FORMAT_S16_LE;
704 } else if (!strncmp(format_str, "s24le", SOUND_SAMPLE_FORMAT_LEN)) {
705 *format = SOUND_SAMPLE_FORMAT_S24_LE;
706 } else if (!strncmp(format_str, "s24-32le", SOUND_SAMPLE_FORMAT_LEN)) {
707 *format = SOUND_SAMPLE_FORMAT_S24_32_LE;
709 LOGE("not supported sample format(%s)", format_str);
710 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
713 LOGI("format[%s, %d]", format_str, *format);
715 return SOUND_MANAGER_ERROR_NONE;
718 int _convert_sample_rate_enum_to_uint(sound_sample_rate_e rate, unsigned int *sample_rate)
720 SM_ARG_CHECK(sample_rate);
723 case SOUND_SAMPLE_RATE_8000:
726 case SOUND_SAMPLE_RATE_16000:
727 *sample_rate = 16000;
729 case SOUND_SAMPLE_RATE_22050:
730 *sample_rate = 22050;
732 case SOUND_SAMPLE_RATE_44100:
733 *sample_rate = 44100;
735 case SOUND_SAMPLE_RATE_48000:
736 *sample_rate = 48000;
738 case SOUND_SAMPLE_RATE_88200:
739 *sample_rate = 88200;
741 case SOUND_SAMPLE_RATE_96000:
742 *sample_rate = 96000;
744 case SOUND_SAMPLE_RATE_192000:
745 *sample_rate = 192000;
748 LOGE("not supported sample rate(%u)", rate);
749 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
752 return SOUND_MANAGER_ERROR_NONE;
755 int _convert_sample_rate_to_enum(unsigned int rate, sound_sample_rate_e *rate_e)
757 SM_ARG_CHECK(rate_e);
761 *rate_e = SOUND_SAMPLE_RATE_8000;
764 *rate_e = SOUND_SAMPLE_RATE_16000;
767 *rate_e = SOUND_SAMPLE_RATE_22050;
770 *rate_e = SOUND_SAMPLE_RATE_44100;
773 *rate_e = SOUND_SAMPLE_RATE_48000;
776 *rate_e = SOUND_SAMPLE_RATE_88200;
779 *rate_e = SOUND_SAMPLE_RATE_96000;
782 *rate_e = SOUND_SAMPLE_RATE_192000;
785 LOGE("not supported sample rate(%u)", rate);
786 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
789 LOGI("rate[%d, %d]", rate, *rate_e);
791 return SOUND_MANAGER_ERROR_NONE;
795 int _return_val_if_not_usb_device(sound_device_h device, int ret_val)
797 mm_sound_device_type_e type;
799 if (mm_sound_get_device_type(device, &type))
802 if (type != MM_SOUND_DEVICE_TYPE_USB_AUDIO) {
803 LOGE("device type is not USB AUDIO");
807 return SOUND_MANAGER_ERROR_NONE;
811 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)
813 int ret = MM_ERROR_NONE;
814 sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
815 sound_stream_info_s *stream_info;
820 LOGE("user_data is null");
824 stream_info = (sound_stream_info_s *)user_data;
825 if (stream_info->focus_id != index) {
826 LOGE("index is not valid, (%d, %d)", stream_info->focus_id, index);
830 if ((ret = _convert_stream_type_to_change_reason(reason, &change_reason)) != SOUND_MANAGER_ERROR_NONE) {
831 LOGE("failed to _convert_stream_type_to_enum(), reason(%s), err(0x%08x)", reason, ret);
835 SM_ENTER_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
837 if (state == FOCUS_IS_RELEASED)
838 stream_info->acquired_focus &= ~focus_type;
839 else if (state == FOCUS_IS_ACQUIRED)
840 stream_info->acquired_focus |= focus_type;
842 if (state == FOCUS_IS_ACQUIRED)
843 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
845 LOGI("[FOCUS USER CALLBACK(%p) START]", stream_info->user_cb);
846 stream_info->user_cb((sound_stream_info_h)stream_info, focus_type, state, change_reason,
847 option, extra_info, stream_info->user_data);
848 LOGI("[FOCUS USER CALLBACK(%p) END]", stream_info->user_cb);
850 if (state == FOCUS_IS_RELEASED)
851 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
853 if (state == FOCUS_IS_RELEASED)
854 stream_info->prev_acquired_focus &= ~focus_type;
855 else if (state == FOCUS_IS_ACQUIRED)
856 stream_info->prev_acquired_focus |= focus_type;
858 SM_LEAVE_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
866 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)
868 int ret = MM_ERROR_NONE;
869 sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
870 _focus_watch_info_s *watch_info;
875 LOGE("user_data is null");
879 watch_info = (_focus_watch_info_s *)user_data;
880 if (watch_info->id != index) {
881 LOGE("index is not valid, (%d, %d)", watch_info->id, index);
885 if ((ret = _convert_stream_type_to_change_reason(reason, &change_reason)) != SOUND_MANAGER_ERROR_NONE) {
886 LOGE("failed to _convert_stream_type_to_enum(), reason(%s), err(0x%08x)", reason, ret);
890 LOGI("[FOCUS WATCH USER CALLBACK(%p, id:%d) START]", watch_info->user_cb, index);
891 watch_info->user_cb(index, focus_type, state, change_reason, extra_info, watch_info->user_data);
892 LOGI("[FOCUS WATCH USER CALLBACK(%p) END]", watch_info->user_cb);
901 void _pa_context_state_cb(pa_context *c, void *userdata)
903 pa_context_state_t state;
904 sound_pa_info_s *pa_info = (sound_pa_info_s *)userdata;
907 LOGE("pa_context is null");
912 LOGE("pa_info is null");
916 state = pa_context_get_state(c);
918 LOGI("pa_info[%p] context state[%d]", pa_info, state);
920 if (state == PA_CONTEXT_FAILED) {
921 pa_info->is_disconnected = true;
922 LOGE("PA DISCONNECTED");
926 case PA_CONTEXT_READY:
927 case PA_CONTEXT_TERMINATED:
928 case PA_CONTEXT_FAILED:
929 pa_threaded_mainloop_signal(pa_info->mainloop, 0);
931 case PA_CONTEXT_UNCONNECTED:
932 case PA_CONTEXT_CONNECTING:
933 case PA_CONTEXT_AUTHORIZING:
934 case PA_CONTEXT_SETTING_NAME:
942 void _pa_stream_state_cb(pa_stream *s, void *userdata)
944 pa_stream_state_t state;
945 virtual_sound_stream_info_s *vstream_h = (virtual_sound_stream_info_s*)userdata;
948 LOGE("pa_stream is null");
953 LOGE("vstream_h is null");
957 state = pa_stream_get_state(s);
958 LOGI("vstream_h[%p] index[%d] state[%d]", vstream_h, pa_stream_get_index(s), state);
961 case PA_STREAM_READY:
962 case PA_STREAM_FAILED:
963 case PA_STREAM_TERMINATED:
964 pa_threaded_mainloop_signal(vstream_h->pa_mainloop, 0);
966 case PA_STREAM_UNCONNECTED:
967 case PA_STREAM_CREATING:
975 int _get_stream_conf_info(const char *stream_type, stream_conf_info_s *info)
977 int ret = SOUND_MANAGER_ERROR_NONE;
978 GVariant *result = NULL;
979 GVariant *child = NULL;
980 GDBusConnection *conn = NULL;
983 GVariant *item = NULL;
988 SM_ARG_CHECK(stream_type);
991 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
994 result = g_dbus_connection_call_sync(conn,
996 PA_STREAM_MANAGER_OBJECT_PATH,
997 PA_STREAM_MANAGER_INTERFACE,
998 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO,
999 g_variant_new("(s)", stream_type),
1000 G_VARIANT_TYPE("(vvvvvv)"),
1001 G_DBUS_CALL_FLAGS_NONE,
1002 DBUS_METHOD_TIMEOUT,
1005 if (!result || err) {
1007 LOGE("g_dbus_connection_call_sync() for GET_STREAM_INFO error (%s)", err ? err->message : NULL);
1010 ret = SOUND_MANAGER_ERROR_INTERNAL;
1016 child = g_variant_get_child_value(result, 0);
1017 item = g_variant_get_variant(child);
1018 info->priority = g_variant_get_int32(item);
1019 g_variant_unref(item);
1020 g_variant_unref(child);
1021 LOGI("priority(%d)", info->priority);
1023 /* get route type */
1024 child = g_variant_get_child_value(result, 1);
1025 item = g_variant_get_variant(child);
1026 info->route_type = g_variant_get_int32(item);
1027 g_variant_unref(item);
1028 g_variant_unref(child);
1029 LOGI("route_type(%d)", info->route_type);
1031 /* get volume types */
1032 child = g_variant_get_child_value(result, 2);
1033 item = g_variant_get_variant(child);
1034 g_variant_iter_init(&iter, item);
1035 while (g_variant_iter_loop(&iter, "&s", &name)) {
1036 if (name && !strncmp(name, "none", strlen("none")))
1038 /* we use volume type only for out direction */
1040 LOGI(" volume-type : %s", name);
1041 info->volume_type = strdup(name);
1045 g_variant_unref(item);
1046 g_variant_unref(child);
1048 /* get available in-devices */
1049 child = g_variant_get_child_value(result, 3);
1050 item = g_variant_get_variant(child);
1051 size = g_variant_n_children(item);
1052 LOGI("num of avail-in-devices are %"G_GSIZE_FORMAT, size);
1053 g_variant_iter_init(&iter, item);
1055 while (g_variant_iter_loop(&iter, "&s", &name)) {
1056 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1057 LOGI(" in-device is [%s], skip it", name);
1060 LOGI(" in-device name : %s", name);
1061 info->avail_in_devices[i++] = strdup(name);
1063 g_variant_unref(item);
1064 g_variant_unref(child);
1066 /* get available out-devices */
1067 child = g_variant_get_child_value(result, 4);
1068 item = g_variant_get_variant(child);
1069 size = g_variant_n_children(item);
1070 LOGI("num of avail-out-devices are %"G_GSIZE_FORMAT, size);
1071 g_variant_iter_init(&iter, item);
1073 while (g_variant_iter_loop(&iter, "&s", &name)) {
1074 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1075 LOGI(" out-device is [%s], skip it", name);
1078 LOGI(" out-device name : %s", name);
1079 info->avail_out_devices[i++] = strdup(name);
1081 g_variant_unref(item);
1082 g_variant_unref(child);
1084 /* get available frameworks */
1085 child = g_variant_get_child_value(result, 5);
1086 item = g_variant_get_variant(child);
1087 size = g_variant_n_children(item);
1088 LOGI("num of avail-frameworks are %"G_GSIZE_FORMAT, size);
1089 g_variant_iter_init(&iter, item);
1091 while (g_variant_iter_loop(&iter, "&s", &name)) {
1092 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1093 LOGI(" framework is [%s], skip it", name);//LCOV_EXCL_LINE
1096 LOGI(" framework name : %s", name);
1097 info->avail_frameworks[i++] = strdup(name);
1099 g_variant_unref(item);
1100 g_variant_unref(child);
1102 if (info->priority == -1) {
1103 LOGE("could not find the info of stream type(%s)", stream_type);//LCOV_EXCL_LINE
1104 ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
1109 g_variant_unref(result);
1110 g_object_unref(conn);
1115 int _set_manual_route_info(unsigned int index, manual_route_info_s *info)
1117 int ret = SOUND_MANAGER_ERROR_NONE;
1119 GVariantBuilder *builder_for_in_devices;
1120 GVariantBuilder *builder_for_out_devices;
1121 GVariant *result = NULL;
1122 GDBusConnection *conn = NULL;
1124 const gchar *dbus_ret = NULL;
1128 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1131 LOGI("index[%u]", index);
1133 builder_for_in_devices = g_variant_builder_new(G_VARIANT_TYPE("au"));
1134 builder_for_out_devices = g_variant_builder_new(G_VARIANT_TYPE("au"));
1135 if (!builder_for_in_devices || !builder_for_out_devices) {
1136 LOGE("failed to g_variant_builder_new(), builder_for_in_devices(%p), builder_for_out_devices(%p)",
1137 builder_for_in_devices, builder_for_out_devices);
1138 ret = SOUND_MANAGER_ERROR_INTERNAL;
1141 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1142 if (!info->route_in_devices[i])
1144 g_variant_builder_add(builder_for_in_devices, "u", info->route_in_devices[i]);
1145 LOGI("[IN] device_id:%u", info->route_in_devices[i]);
1147 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1148 if (!info->route_out_devices[i])
1150 g_variant_builder_add(builder_for_out_devices, "u", info->route_out_devices[i]);
1151 LOGI("[OUT] device_id:%u", info->route_out_devices[i]);
1154 result = g_dbus_connection_call_sync(conn,
1156 PA_STREAM_MANAGER_OBJECT_PATH,
1157 PA_STREAM_MANAGER_INTERFACE,
1158 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES,
1159 g_variant_new("(uauau)", index, builder_for_in_devices, builder_for_out_devices),
1160 G_VARIANT_TYPE("(s)"),
1161 G_DBUS_CALL_FLAGS_NONE,
1162 DBUS_METHOD_TIMEOUT,
1165 if (!result || err) {
1167 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_DEVICES error (%s)", err ? err->message : NULL);
1170 ret = SOUND_MANAGER_ERROR_INTERNAL;
1175 g_variant_get(result, "(&s)", &dbus_ret);
1177 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1178 ret = SOUND_MANAGER_ERROR_INTERNAL;
1180 info->is_set = true;
1182 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1186 g_variant_unref(result);
1187 if (builder_for_in_devices)
1188 g_variant_builder_unref(builder_for_in_devices);
1189 if (builder_for_out_devices)
1190 g_variant_builder_unref(builder_for_out_devices);
1191 g_object_unref(conn);
1197 int _set_route_option(unsigned int index, const char *name, int value)
1199 int ret = SOUND_MANAGER_ERROR_NONE;
1200 GVariant *result = NULL;
1201 GDBusConnection *conn = NULL;
1203 const gchar *dbus_ret = NULL;
1207 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1210 LOGI("index[%u] name[%s] value[%d]", index, name, value);
1212 result = g_dbus_connection_call_sync(conn,
1214 PA_STREAM_MANAGER_OBJECT_PATH,
1215 PA_STREAM_MANAGER_INTERFACE,
1216 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION,
1217 g_variant_new("(usi)", index, name, value),
1218 G_VARIANT_TYPE("(s)"),
1219 G_DBUS_CALL_FLAGS_NONE,
1220 DBUS_METHOD_TIMEOUT,
1223 if (!result || err) {
1224 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_OPTION error (%s)", err ? err->message : NULL);
1227 ret = SOUND_MANAGER_ERROR_INTERNAL;
1231 g_variant_get(result, "(&s)", &dbus_ret);
1233 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
1234 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
1235 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1236 ret = SOUND_MANAGER_ERROR_INTERNAL;
1238 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1242 g_variant_unref(result);
1243 g_object_unref(conn);
1249 int _get_volume_max_level(const char *direction, const char *volume_type, unsigned int *max_level)
1251 int ret = SOUND_MANAGER_ERROR_NONE;
1252 GVariant *result = NULL;
1253 GDBusConnection *conn = NULL;
1255 const gchar *dbus_ret = NULL;
1257 SM_ARG_CHECK(direction);
1258 SM_ARG_CHECK(volume_type);
1259 SM_ARG_CHECK(max_level);
1261 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1264 result = g_dbus_connection_call_sync(conn,
1266 PA_STREAM_MANAGER_OBJECT_PATH,
1267 PA_STREAM_MANAGER_INTERFACE,
1268 PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL,
1269 g_variant_new("(ss)", direction, volume_type),
1270 G_VARIANT_TYPE("(us)"),
1271 G_DBUS_CALL_FLAGS_NONE,
1272 DBUS_METHOD_TIMEOUT,
1275 if (!result || err) {
1277 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_MAX_LEVEL error (%s)", err ? err->message : NULL);
1280 ret = SOUND_MANAGER_ERROR_INTERNAL;
1285 g_variant_get(result, "(u&s)", max_level, &dbus_ret);
1287 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1288 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1290 LOGI("max_level[%u]", *max_level);
1292 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1296 g_variant_unref(result);
1297 g_object_unref(conn);
1303 int _get_volume_level(const char *direction, const char *volume_type, unsigned int *level)
1305 int ret = SOUND_MANAGER_ERROR_NONE;
1306 GVariant *result = NULL;
1307 GDBusConnection *conn = NULL;
1309 const gchar *dbus_ret = NULL;
1311 SM_ARG_CHECK(direction);
1312 SM_ARG_CHECK(volume_type);
1313 SM_ARG_CHECK(level);
1315 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1318 result = g_dbus_connection_call_sync(conn,
1320 PA_STREAM_MANAGER_OBJECT_PATH,
1321 PA_STREAM_MANAGER_INTERFACE,
1322 PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL,
1323 g_variant_new("(ss)", direction, volume_type),
1324 G_VARIANT_TYPE("(us)"),
1325 G_DBUS_CALL_FLAGS_NONE,
1326 DBUS_METHOD_TIMEOUT,
1329 if (!result || err) {
1330 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1333 ret = SOUND_MANAGER_ERROR_INTERNAL;
1337 g_variant_get(result, "(u&s)", level, &dbus_ret);
1339 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1340 ret = SOUND_MANAGER_ERROR_INTERNAL;
1342 LOGI("level[%u]", *level);
1344 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1348 g_variant_unref(result);
1349 g_object_unref(conn);
1354 int _set_volume_level(const char *direction, const char *volume_type, unsigned int level)
1356 int ret = SOUND_MANAGER_ERROR_NONE;
1357 GVariant *result = NULL;
1358 GDBusConnection *conn = NULL;
1360 const gchar *dbus_ret = NULL;
1362 char volume_path[VCONF_PATH_MAX] = {0,};
1364 SM_ARG_CHECK(direction);
1365 SM_ARG_CHECK(volume_type);
1367 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1370 result = g_dbus_connection_call_sync(conn,
1372 PA_STREAM_MANAGER_OBJECT_PATH,
1373 PA_STREAM_MANAGER_INTERFACE,
1374 PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL,
1375 g_variant_new("(ssu)", direction, volume_type, level),
1376 G_VARIANT_TYPE("(s)"),
1377 G_DBUS_CALL_FLAGS_NONE,
1378 DBUS_METHOD_TIMEOUT,
1381 if (!result || err) {
1382 LOGE("g_dbus_connection_call_sync() for SET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1385 ret = SOUND_MANAGER_ERROR_INTERNAL;
1389 g_variant_get(result, "(&s)", &dbus_ret);
1391 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1392 ret = SOUND_MANAGER_ERROR_INTERNAL;
1394 /* Set volume value to VCONF */
1395 snprintf(volume_path, sizeof(volume_path)-1, "%s%s", VCONF_PATH_PREFIX_VOLUME, volume_type);
1396 if ((vret = vconf_set_int(volume_path, (int)level)))
1397 LOGE("vconf_set_int(%s) failed..ret[%d]\n", volume_path, vret);
1400 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1404 g_variant_unref(result);
1405 g_object_unref(conn);
1411 int _get_current_volume_type(const char *direction, char **volume_type)
1413 int ret = SOUND_MANAGER_ERROR_NONE;
1414 GVariant *result = NULL;
1415 GDBusConnection *conn = NULL;
1417 const gchar *dbus_volume_type = NULL;
1418 const gchar *dbus_ret = NULL;
1420 SM_ARG_CHECK(direction);
1421 SM_ARG_CHECK(volume_type);
1423 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1426 result = g_dbus_connection_call_sync(conn,
1428 PA_STREAM_MANAGER_OBJECT_PATH,
1429 PA_STREAM_MANAGER_INTERFACE,
1430 PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE,
1431 g_variant_new("(s)", direction),
1432 G_VARIANT_TYPE("(ss)"),
1433 G_DBUS_CALL_FLAGS_NONE,
1434 DBUS_METHOD_TIMEOUT,
1437 if (!result || err) {
1439 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_VOLUME_TYPE error (%s)", err ? err->message : NULL);
1442 ret = SOUND_MANAGER_ERROR_INTERNAL;
1447 g_variant_get(result, "(&s&s)", &dbus_volume_type, &dbus_ret);
1449 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
1450 ret = SOUND_MANAGER_ERROR_NONE;//LCOV_EXCL_LINE
1451 *volume_type = strdup(dbus_volume_type);//LCOV_EXCL_LINE
1452 LOGI("volume_type[%s]", *volume_type);
1453 } else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret))) {
1454 ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
1456 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1459 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1463 g_variant_unref(result);
1464 g_object_unref(conn);
1469 int _get_current_media_routing_path(const char *direction, sound_device_type_e *device_type)
1471 int ret = SOUND_MANAGER_ERROR_NONE;
1472 GVariant *result = NULL;
1473 GDBusConnection *conn = NULL;
1475 const gchar *dbus_device_type = NULL;
1476 const gchar *dbus_ret = NULL;
1478 SM_ARG_CHECK(direction);
1479 SM_ARG_CHECK(device_type);
1481 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1484 result = g_dbus_connection_call_sync(conn,
1486 PA_STREAM_MANAGER_OBJECT_PATH,
1487 PA_STREAM_MANAGER_INTERFACE,
1488 PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH,
1489 g_variant_new("(s)", direction),
1490 G_VARIANT_TYPE("(ss)"),
1491 G_DBUS_CALL_FLAGS_NONE,
1492 DBUS_METHOD_TIMEOUT,
1495 if (!result || err) {
1497 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_MEDIA_ROUTING_PATH error (%s)", err ? err->message : NULL);
1500 ret = SOUND_MANAGER_ERROR_INTERNAL;
1505 g_variant_get(result, "(&s&s)", &dbus_device_type, &dbus_ret);
1507 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
1508 if (_convert_device_type_str_to_enum(dbus_device_type, device_type) < 0)
1509 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1511 if (!strncmp("none", dbus_device_type, strlen(dbus_device_type)))
1512 ret = SOUND_MANAGER_ERROR_NO_DATA;
1514 ret = SOUND_MANAGER_ERROR_INTERNAL;
1517 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
1521 g_variant_unref(result);
1522 g_object_unref(conn);
1527 void _update_focus_status(unsigned int index, unsigned int acquired_focus_status)
1529 GVariant *result = NULL;
1530 GDBusConnection *conn = NULL;
1532 const gchar *dbus_ret = NULL;
1534 if (__get_dbus_connection(&conn))
1537 result = g_dbus_connection_call_sync(conn,
1539 PA_STREAM_MANAGER_OBJECT_PATH,
1540 PA_STREAM_MANAGER_INTERFACE,
1541 PA_STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS,
1542 g_variant_new("(uu)", index, acquired_focus_status),
1543 G_VARIANT_TYPE("(s)"),
1544 G_DBUS_CALL_FLAGS_NONE,
1545 DBUS_METHOD_TIMEOUT,
1548 if (!result || err) {
1550 LOGE("g_dbus_connection_call_sync() for UPDATE_FOCUS_STATUS error (%s)", err ? err->message : NULL);
1556 g_variant_get(result, "(&s)", &dbus_ret);
1557 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1558 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1559 LOGE("failed to UPDATE_FOCUS_STATUS error (%s)", dbus_ret);//LCOV_EXCL_LINE
1563 g_variant_unref(result);
1564 g_object_unref(conn);
1568 int _is_device_running_by_id(int device_id, bool *is_running)
1570 int ret = SOUND_MANAGER_ERROR_NONE;
1571 GVariant *result = NULL;
1572 GDBusConnection *conn = NULL;
1574 gboolean _is_running;
1576 SM_ARG_CHECK(is_running);
1578 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1581 result = g_dbus_connection_call_sync(conn,
1583 PA_DEVICE_MANAGER_OBJECT_PATH,
1584 PA_DEVICE_MANAGER_INTERFACE,
1585 PA_DEVICE_MANAGER_METHOD_NAME_IS_DEVICE_RUNNING_BY_ID,
1586 g_variant_new("(i)", device_id),
1587 G_VARIANT_TYPE("(b)"),
1588 G_DBUS_CALL_FLAGS_NONE,
1589 DBUS_METHOD_TIMEOUT,
1593 LOGE("g_dbus_connection_call_sync() for IS_DEVICE_RUNNING_BY_ID error (%s)", err->message);
1594 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1598 g_variant_get(result, "(b)", &_is_running);
1599 *is_running = (bool)_is_running;
1600 LOGI("device_id[%d] is [%s]", device_id, *is_running ? "Running" : "Not running");
1605 g_variant_unref(result);
1606 g_object_unref(conn);
1611 #define SM_SAMPLE_FORMAT_NUM 4 /* check declaration of sound_sample_format_e */
1612 int _get_supported_sample_formats(int device_id, sound_sample_format_e **formats, unsigned int *num)
1614 int ret = SOUND_MANAGER_ERROR_NONE;
1615 GVariant *result = NULL;
1616 GDBusConnection *conn = NULL;
1618 GVariantIter *iter = NULL;
1620 unsigned int iter_num;
1621 unsigned int elem_num = 0;
1622 sound_sample_format_e format;
1623 sound_sample_format_e sm_formats[SM_SAMPLE_FORMAT_NUM] = {0, };
1625 SM_ARG_CHECK(formats);
1628 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1631 result = g_dbus_connection_call_sync(conn,
1633 PA_DEVICE_MANAGER_OBJECT_PATH,
1634 PA_DEVICE_MANAGER_INTERFACE,
1635 PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_FORMATS,
1636 g_variant_new("(i)", device_id),
1637 G_VARIANT_TYPE("(as)"),
1638 G_DBUS_CALL_FLAGS_NONE,
1639 DBUS_METHOD_TIMEOUT,
1642 if (!result || err) {
1643 LOGE("g_dbus_connection_call_sync() for GET_SUPPORTED_SAMPLE_FORMATS error (%s)", err ? err->message : NULL);
1644 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1650 g_variant_get(result, "(as)", &iter);
1651 if ((iter_num = (unsigned int) g_variant_iter_n_children(iter)) == 0) {
1652 LOGE("could not get supported sample formats");
1653 ret = SOUND_MANAGER_ERROR_INTERNAL;
1657 while (g_variant_iter_loop(iter, "&s", &format_str)) {
1658 if (_convert_sample_format_str_to_enum((const char *)format_str, &format) != SOUND_MANAGER_ERROR_NONE)
1661 sm_formats[elem_num - 1] = format;
1664 if (elem_num == 0) {
1665 LOGE("could not find supported sample formats");
1666 ret = SOUND_MANAGER_ERROR_INTERNAL;
1670 if (!(*formats = (sound_sample_format_e *) calloc(elem_num, sizeof(sound_sample_format_e)))) {
1671 LOGE("failed to calloc(), elem_num(%d)", elem_num);
1672 ret = SOUND_MANAGER_ERROR_INTERNAL;
1675 memcpy(*formats, sm_formats, elem_num * sizeof(sound_sample_format_e));
1680 LOGI("num[%d]", *num);
1684 g_variant_iter_free(iter);
1686 g_variant_unref(result);
1687 g_object_unref(conn);
1692 int _set_sample_format(int device_id, sound_sample_format_e format)
1694 int ret = SOUND_MANAGER_ERROR_NONE;
1695 GDBusConnection *conn = NULL;
1696 GVariant *result = NULL;
1698 char *format_str = NULL;
1700 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1703 if ((ret = _convert_sample_format_enum_to_str(format, &format_str)) != SOUND_MANAGER_ERROR_NONE)
1706 result = g_dbus_connection_call_sync(conn,
1708 PA_DEVICE_MANAGER_OBJECT_PATH,
1709 PA_DEVICE_MANAGER_INTERFACE,
1710 PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_FORMAT,
1711 g_variant_new("(is)", device_id, format_str),
1713 G_DBUS_CALL_FLAGS_NONE,
1714 DBUS_METHOD_TIMEOUT,
1718 LOGE("g_dbus_connection_call_sync() for SET_SAMPLE_FORMAT error (%s)", err->message);
1719 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1724 g_variant_unref(result);
1726 g_object_unref(conn);
1731 int _get_sample_format(int device_id, sound_sample_format_e *format)
1733 int ret = SOUND_MANAGER_ERROR_NONE;
1734 GVariant *result = NULL;
1735 GDBusConnection *conn = NULL;
1738 sound_sample_format_e format_e;
1740 SM_ARG_CHECK(format);
1742 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1745 result = g_dbus_connection_call_sync(conn,
1747 PA_DEVICE_MANAGER_OBJECT_PATH,
1748 PA_DEVICE_MANAGER_INTERFACE,
1749 PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_FORMAT,
1750 g_variant_new("(i)", device_id),
1751 G_VARIANT_TYPE("(s)"),
1752 G_DBUS_CALL_FLAGS_NONE,
1753 DBUS_METHOD_TIMEOUT,
1756 if (!result || err) {
1757 LOGE("g_dbus_connection_call_sync() for GET_SAMPLE_FORMAT error (%s)", err ? err->message : NULL);
1758 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1763 g_variant_get(result, "(&s)", &format_str);
1764 if ((ret = _convert_sample_format_str_to_enum((const char *)format_str, &format_e)) == SOUND_MANAGER_ERROR_NONE)
1769 g_variant_unref(result);
1770 g_object_unref(conn);
1775 #define SM_SAMPLE_RATE_NUM 8 /* check declaration of sound_sample_rate_e */
1776 int _get_supported_sample_rates(int device_id, sound_sample_rate_e **rates, unsigned int *num)
1778 int ret = SOUND_MANAGER_ERROR_NONE;
1779 GVariant *result = NULL;
1780 GDBusConnection *conn = NULL;
1782 GVariantIter *iter = NULL;
1784 unsigned int iter_num;
1785 unsigned int elem_num = 0;
1786 sound_sample_rate_e rate_e;
1787 sound_sample_rate_e sm_rates[SM_SAMPLE_RATE_NUM] = {0, };
1789 SM_ARG_CHECK(rates);
1792 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1795 result = g_dbus_connection_call_sync(conn,
1797 PA_DEVICE_MANAGER_OBJECT_PATH,
1798 PA_DEVICE_MANAGER_INTERFACE,
1799 PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_RATES,
1800 g_variant_new("(i)", device_id),
1801 G_VARIANT_TYPE("(au)"),
1802 G_DBUS_CALL_FLAGS_NONE,
1803 DBUS_METHOD_TIMEOUT,
1806 if (!result || err) {
1807 LOGE("g_dbus_connection_call_sync() for GET_SUPPORTED_SAMPLE_RATES error (%s)", err ? err->message : NULL);
1808 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1814 g_variant_get(result, "(au)", &iter);
1815 if ((iter_num = (unsigned int) g_variant_iter_n_children(iter)) == 0) {
1816 LOGE("could not get supported sample rates");
1817 ret = SOUND_MANAGER_ERROR_INTERNAL;
1821 while (g_variant_iter_loop(iter, "u", &rate)) {
1822 if (_convert_sample_rate_to_enum(rate, &rate_e) != SOUND_MANAGER_ERROR_NONE)
1825 sm_rates[elem_num - 1] = rate_e;
1828 if (elem_num == 0) {
1829 LOGE("could not find supported sample rates");
1830 ret = SOUND_MANAGER_ERROR_INTERNAL;
1834 if (!(*rates = (sound_sample_rate_e *) calloc(elem_num, sizeof(sound_sample_rate_e)))) {
1835 LOGE("failed to calloc(), elem_num(%d)", elem_num);
1836 ret = SOUND_MANAGER_ERROR_INTERNAL;
1839 memcpy(*rates, sm_rates, elem_num * sizeof(sound_sample_rate_e));
1844 LOGI("num[%d]", *num);
1848 g_variant_iter_free(iter);
1850 g_variant_unref(result);
1851 g_object_unref(conn);
1856 int _set_sample_rate(int device_id, sound_sample_rate_e rate)
1858 int ret = SOUND_MANAGER_ERROR_NONE;
1859 GDBusConnection *conn = NULL;
1860 GVariant *result = NULL;
1864 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1867 if ((ret = _convert_sample_rate_enum_to_uint(rate, &_rate)) != SOUND_MANAGER_ERROR_NONE)
1870 result = g_dbus_connection_call_sync(conn,
1872 PA_DEVICE_MANAGER_OBJECT_PATH,
1873 PA_DEVICE_MANAGER_INTERFACE,
1874 PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_RATE,
1875 g_variant_new("(iu)", device_id, _rate),
1877 G_DBUS_CALL_FLAGS_NONE,
1878 DBUS_METHOD_TIMEOUT,
1882 LOGE("g_dbus_connection_call_sync() for SET_SAMPLE_RATE error (%s)", err->message);
1883 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1888 g_variant_unref(result);
1890 g_object_unref(conn);
1895 int _get_sample_rate(int device_id, sound_sample_rate_e *rate)
1897 int ret = SOUND_MANAGER_ERROR_NONE;
1898 GVariant *result = NULL;
1899 GDBusConnection *conn = NULL;
1902 sound_sample_rate_e rate_e;
1906 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1909 result = g_dbus_connection_call_sync(conn,
1911 PA_DEVICE_MANAGER_OBJECT_PATH,
1912 PA_DEVICE_MANAGER_INTERFACE,
1913 PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_RATE,
1914 g_variant_new("(i)", device_id),
1915 G_VARIANT_TYPE("(u)"),
1916 G_DBUS_CALL_FLAGS_NONE,
1917 DBUS_METHOD_TIMEOUT,
1920 if (!result || err) {
1921 LOGE("g_dbus_connection_call_sync() for GET_SAMPLE_RATE error (%s)", err ? err->message : NULL);
1922 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1927 g_variant_get(result, "(u)", &_rate);
1928 if ((ret = _convert_sample_rate_to_enum(_rate, &rate_e)) == SOUND_MANAGER_ERROR_NONE)
1933 g_variant_unref(result);
1934 g_object_unref(conn);
1939 int _set_avoid_resampling(int device_id, bool enable)
1941 int ret = SOUND_MANAGER_ERROR_NONE;
1942 GDBusConnection *conn = NULL;
1943 GVariant *result = NULL;
1946 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1949 result = g_dbus_connection_call_sync(conn,
1951 PA_DEVICE_MANAGER_OBJECT_PATH,
1952 PA_DEVICE_MANAGER_INTERFACE,
1953 PA_DEVICE_MANAGER_METHOD_NAME_SET_AVOID_RESAMPLING,
1954 g_variant_new("(ib)", device_id, enable),
1956 G_DBUS_CALL_FLAGS_NONE,
1957 DBUS_METHOD_TIMEOUT,
1961 LOGE("g_dbus_connection_call_sync() for SET_AVOID_RESAMPLING error (%s)", err->message);
1962 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1967 g_variant_unref(result);
1969 g_object_unref(conn);
1974 int _get_avoid_resampling(int device_id, bool *enabled)
1976 int ret = SOUND_MANAGER_ERROR_NONE;
1977 GVariant *result = NULL;
1978 GDBusConnection *conn = NULL;
1982 SM_ARG_CHECK(enabled);
1984 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
1987 result = g_dbus_connection_call_sync(conn,
1989 PA_DEVICE_MANAGER_OBJECT_PATH,
1990 PA_DEVICE_MANAGER_INTERFACE,
1991 PA_DEVICE_MANAGER_METHOD_NAME_GET_AVOID_RESAMPLING,
1992 g_variant_new("(i)", device_id),
1993 G_VARIANT_TYPE("(b)"),
1994 G_DBUS_CALL_FLAGS_NONE,
1995 DBUS_METHOD_TIMEOUT,
1998 if (!result || err) {
1999 LOGE("g_dbus_connection_call_sync() for GET_AVOID_RESAMPLING error (%s)", err ? err->message : NULL);
2000 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
2006 g_variant_get(result, "(b)", &_enabled);
2007 *enabled = (bool)_enabled;
2009 LOGI("enabled[%d]", *enabled);
2013 g_variant_unref(result);
2014 g_object_unref(conn);
2019 int _set_media_stream_only(int device_id, bool enable)
2021 int ret = SOUND_MANAGER_ERROR_NONE;
2022 GDBusConnection *conn = NULL;
2023 GVariant *result = NULL;
2025 const char *stream_type;
2027 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
2031 stream_type = STREAM_MEDIA;
2033 stream_type = "none";
2035 result = g_dbus_connection_call_sync(conn,
2037 PA_DEVICE_MANAGER_OBJECT_PATH,
2038 PA_DEVICE_MANAGER_INTERFACE,
2039 PA_DEVICE_MANAGER_METHOD_NAME_SET_SPECIFIC_STREAM,
2040 g_variant_new("(is)", device_id, stream_type),
2042 G_DBUS_CALL_FLAGS_NONE,
2043 DBUS_METHOD_TIMEOUT,
2047 LOGE("g_dbus_connection_call_sync() for SET_SPECIFIC_STREAM error (%s)", err->message);
2048 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
2053 g_variant_unref(result);
2055 g_object_unref(conn);
2060 int _get_media_stream_only(int device_id, bool *enabled)
2062 int ret = SOUND_MANAGER_ERROR_NONE;
2063 GVariant *result = NULL;
2064 GDBusConnection *conn = NULL;
2068 SM_ARG_CHECK(enabled);
2070 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
2073 result = g_dbus_connection_call_sync(conn,
2075 PA_DEVICE_MANAGER_OBJECT_PATH,
2076 PA_DEVICE_MANAGER_INTERFACE,
2077 PA_DEVICE_MANAGER_METHOD_NAME_GET_SPECIFIED_STREAM,
2078 g_variant_new("(i)", device_id),
2079 G_VARIANT_TYPE("(s)"),
2080 G_DBUS_CALL_FLAGS_NONE,
2081 DBUS_METHOD_TIMEOUT,
2084 if (!result || err) {
2085 LOGE("g_dbus_connection_call_sync() for GET_SPECIFIED_STREAM error (%s)", err ? err->message : NULL);
2086 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
2092 g_variant_get(result, "(&s)", &stream_type);
2093 if (!strncmp(stream_type, STREAM_MEDIA, SOUND_STREAM_TYPE_LEN))
2098 LOGI("enabled[%d]", *enabled);
2102 g_variant_unref(result);
2103 g_object_unref(conn);
2109 int _make_pa_connection(sound_pa_info_s *pa_info, const char *context_name)
2113 SM_ARG_CHECK(pa_info);
2115 if (!(pa_info->mainloop = pa_threaded_mainloop_new()))
2118 if (!(pa_info->context = pa_context_new(pa_threaded_mainloop_get_api(pa_info->mainloop), context_name)))
2121 pa_context_set_state_callback(pa_info->context, _pa_context_state_cb, pa_info);
2123 if (pa_context_connect(pa_info->context, NULL, 0, NULL) < 0) {
2124 pa_ret = pa_context_errno(pa_info->context);//LCOV_EXCL_LINE
2128 pa_threaded_mainloop_lock(pa_info->mainloop);
2130 if (pa_threaded_mainloop_start(pa_info->mainloop) < 0)
2131 goto PA_ERROR_WITH_UNLOCK;
2133 /* wait for ready state of the context */
2135 pa_context_state_t state;
2136 state = pa_context_get_state(pa_info->context);
2137 if (state == PA_CONTEXT_READY)
2139 if (!PA_CONTEXT_IS_GOOD(state)) {
2140 pa_ret = pa_context_errno(pa_info->context);//LCOV_EXCL_LINE
2141 goto PA_ERROR_WITH_UNLOCK;
2143 pa_threaded_mainloop_wait(pa_info->mainloop);
2146 /* get index of this context */
2147 pa_info->index = pa_context_get_index(pa_info->context);
2149 pa_threaded_mainloop_unlock(pa_info->mainloop);
2151 return SOUND_MANAGER_ERROR_NONE;
2153 PA_ERROR_WITH_UNLOCK:
2154 pa_threaded_mainloop_unlock(pa_info->mainloop);
2157 _destroy_pa_connection(pa_info);
2158 LOGE("pa_ret %d", pa_ret);
2160 return SOUND_MANAGER_ERROR_INTERNAL;
2164 int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_stream_focus_state_changed_cb callback, void *user_data)
2166 int ret = SOUND_MANAGER_ERROR_NONE;
2167 int mm_ret = MM_ERROR_NONE;
2169 bool is_focus_cb_thread = false;
2171 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
2172 return _convert_sound_manager_error_code(__func__, mm_ret);
2174 if (is_focus_cb_thread)
2175 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2177 /* get configuration information of this stream type */
2178 if ((ret = _get_stream_conf_info(stream_h->stream_type, &stream_h->stream_conf_info)) != SOUND_MANAGER_ERROR_NONE)
2181 LOGI("stream_conf_info : stream type[%s], priority[%d], route type[%d]",
2182 stream_h->stream_type, stream_h->stream_conf_info.priority, stream_h->stream_conf_info.route_type);
2184 if ((ret = _make_pa_connection(&stream_h->pa_info, "SOUND_MANAGER_STREAM_INFO")) != SOUND_MANAGER_ERROR_NONE)
2187 /* register focus */
2188 if (!stream_h->is_focus_unavailable) {
2189 mm_ret = mm_sound_register_focus(stream_h->stream_type, _focus_state_change_callback, stream_h, &stream_h->focus_id);
2190 if (mm_ret == MM_ERROR_NONE) {
2191 stream_h->user_cb = callback;
2192 stream_h->user_data = user_data;
2194 LOGE("failed to register focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2195 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2202 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2203 SM_SAFE_FREE(stream_h->stream_conf_info.avail_in_devices[i]);
2204 SM_SAFE_FREE(stream_h->stream_conf_info.avail_out_devices[i]);
2206 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2207 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2209 SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2211 _destroy_pa_connection(&stream_h->pa_info);
2217 void _destroy_pa_connection(sound_pa_info_s *pa_info)
2220 LOGW("NULL pa info - skip..");
2224 LOGI("[%p][%p]", pa_info->mainloop, pa_info->context);
2226 if (pa_info->mainloop)
2227 pa_threaded_mainloop_stop(pa_info->mainloop);
2229 if (pa_info->context) {
2230 pa_context_disconnect(pa_info->context);
2231 pa_context_unref(pa_info->context);
2232 pa_info->context = NULL;
2235 if (pa_info->mainloop) {
2236 pa_threaded_mainloop_free(pa_info->mainloop);
2237 pa_info->mainloop = NULL;
2241 int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h)
2244 int ret = SOUND_MANAGER_ERROR_NONE;
2245 int mm_ret = MM_ERROR_NONE;
2246 bool is_focus_cb_thread = false;
2248 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
2249 return _convert_sound_manager_error_code(__func__, mm_ret);
2251 if (is_focus_cb_thread)
2252 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2254 _destroy_pa_connection(&stream_h->pa_info);
2256 /* unregister focus */
2257 if (!stream_h->is_focus_unavailable) {
2258 mm_ret = mm_sound_unregister_focus(stream_h->focus_id);
2260 LOGE("failed to unregister focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2261 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2265 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2266 SM_SAFE_FREE(stream_h->stream_conf_info.avail_in_devices[i]);
2267 SM_SAFE_FREE(stream_h->stream_conf_info.avail_out_devices[i]);
2269 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2270 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2272 SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2278 static int __dbus_method_call(const char *method, GVariant *param, GVariant **reply)
2280 GDBusConnection *conn = NULL;
2281 GVariant *_reply = NULL;
2285 if (!method || !param) {
2286 LOGE("invalid parameter");
2287 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
2291 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE) {
2292 ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
2296 _reply = g_dbus_connection_call_sync(conn, PA_BUS_NAME,
2297 PA_STREAM_MANAGER_OBJECT_PATH,
2298 PA_STREAM_MANAGER_INTERFACE,
2299 method, param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
2301 g_object_unref(conn);
2304 ret = _convert_dbus_error(err->message);
2305 LOGE("g_dbus_connection_call_sync() method(%s), err-msg(%s)", method, err->message);
2313 g_variant_unref(_reply);
2315 return SOUND_MANAGER_ERROR_NONE;
2319 g_variant_unref(param);
2325 static struct _publish_info {
2326 GDBusConnection *conn;
2329 sound_manager_remote_client_connected_cb cb;
2334 #define REMOTE_CLIENT_BIT_TYPE_MASK 0x80000000
2335 #define REMOTE_CLIENT_BIT_TYPE 31
2337 static void __internal_cb(GDBusConnection *connection, const gchar *sender_name,
2338 const gchar *object_path, const gchar *interface_name,
2339 const gchar *signal_name,GVariant *params, gpointer userdata)
2341 struct _cb_info *cb_info = (struct _cb_info *)userdata;
2343 if (cb_info && cb_info->cb) {
2346 gboolean is_connected;
2347 gchar *name, *description;
2349 g_variant_get(params, "(iub&s&s)", &type, &id, &is_connected, &name, &description);
2351 LOGE("type(%d), id(%u), is_connected(%d), name(%s), description(%s)",
2352 type, id, is_connected, name, description);
2354 /* MSB:input or output, others:index */
2355 id = id | (type << REMOTE_CLIENT_BIT_TYPE);
2356 cb_info->cb(id, name, type, description, is_connected, cb_info->userdata);
2360 static int __subscribe_remote_devices(sound_manager_remote_client_connected_cb callback, void *userdata)
2363 struct _cb_info *cb_info = &(publish_info.cb_info);
2365 if (publish_info.subs_id > 0) {
2366 LOGE("already subscribed remote device");
2367 return SOUND_MANAGER_ERROR_INTERNAL;
2370 if ((ret = __get_dbus_connection(&publish_info.conn)) != SOUND_MANAGER_ERROR_NONE)
2373 cb_info->cb = callback;
2374 cb_info->userdata = userdata;
2376 publish_info.subs_id = g_dbus_connection_signal_subscribe(publish_info.conn, NULL,
2377 PA_STREAM_MANAGER_INTERFACE,
2378 PA_STREAM_MANAGER_SIGNAL_NAME_REMOTE_FOUND,
2379 PA_STREAM_MANAGER_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
2380 __internal_cb, cb_info, NULL);
2381 if (publish_info.subs_id == 0) {
2382 g_object_unref(publish_info.conn);
2383 LOGE("subscription failed");
2384 return SOUND_MANAGER_ERROR_INTERNAL;
2387 LOGI("subscribe remote devices. subs_id %d", publish_info.subs_id);
2389 return SOUND_MANAGER_ERROR_NONE;
2392 static int __unsubscribe_remote_devices(void)
2396 if (publish_info.subs_id == 0) {
2397 LOGE("invalid subs_id(%d)", publish_info.subs_id);
2398 return SOUND_MANAGER_ERROR_INTERNAL;
2401 if ((ret = __get_dbus_connection(&publish_info.conn)) != SOUND_MANAGER_ERROR_NONE)
2404 g_dbus_connection_signal_unsubscribe(publish_info.conn, publish_info.subs_id);
2406 if (publish_info.conn) {
2407 g_object_unref(publish_info.conn);
2408 publish_info.conn = NULL;
2411 publish_info.subs_id = 0;
2413 LOGI("unsubscribe remote devices state subs_id %d", publish_info.subs_id);
2415 return SOUND_MANAGER_ERROR_NONE;
2418 int _publish_local_device(sound_manager_remote_client_connected_cb callback, void *user_data)
2422 LOGI("publish local device callback(%p), userdata(%p)", callback, user_data);
2424 ret = __subscribe_remote_devices(callback, user_data);
2425 if (ret != SOUND_MANAGER_ERROR_NONE) {
2426 LOGE("subscribe failed");
2430 ret = __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_PUBLISH_LOCAL_DEVICE, g_variant_new("(b)", TRUE), NULL);
2431 if (ret != SOUND_MANAGER_ERROR_NONE) {
2432 if (__unsubscribe_remote_devices())
2433 LOGE("unsubscribe failed");
2435 LOGE("publish local device failed");
2443 int _unpublish_local_device(void)
2447 ret = __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_PUBLISH_LOCAL_DEVICE, g_variant_new("(b)", FALSE), NULL);
2448 if (ret != SOUND_MANAGER_ERROR_NONE) {
2449 LOGE("unpublish local device failed");
2453 ret = __unsubscribe_remote_devices();
2454 if (ret != SOUND_MANAGER_ERROR_NONE) {
2455 LOGE("unsubscribe failed");
2462 int _discover_remote_device(bool enable)
2464 return __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_DISCOVER_REMOTE_DEVICE,
2465 g_variant_new("(b)", (gboolean)enable), NULL);
2468 int _set_remote_permission(int id, bool allowed)
2471 int index = (id << 1) >> 1;
2472 char *type = id & REMOTE_CLIENT_BIT_TYPE_MASK ? "source-output" : "sink-input";
2474 LOGI("id(%d), allowed(%d), index(%d), type(%s)", id, allowed, index, type);
2476 ret = __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_SET_REMOTE_PERMISSION,
2477 g_variant_new("(sub)", type, index, (gboolean)allowed), NULL);
2478 if (ret != SOUND_MANAGER_ERROR_NONE)
2479 LOGE("update proplist failed");
2484 int _set_echo_cancel_reference_device(sound_stream_info_s *stream_info, sound_device_h device)
2490 SM_ARG_CHECK(stream_info);
2491 SM_ARG_CHECK(device);
2493 if (!stream_info->stream_conf_info.avail_in_devices[0]) {
2494 LOGE("stream_info[%p, %s] does not support any input devices", stream_info, stream_info->stream_type);
2495 return SOUND_MANAGER_ERROR_POLICY;
2498 /* FIXME: check if the PA sink supports to pump the reference data to AEC module */
2499 if ((ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
2500 return _convert_sound_manager_error_code(__func__, ret);
2502 if ((ret = mm_sound_get_device_name(device, &device_name)) != MM_ERROR_NONE)
2503 return _convert_sound_manager_error_code(__func__, ret);
2505 stream_info->echo_cancel_reference_device = device_id;
2507 LOGI("stream_info[%p, %s] EC reference device[id:%d, name:%s]",
2508 stream_info, stream_info->stream_type, device_id, device_name);
2510 return SOUND_MANAGER_ERROR_NONE;
2513 int _get_echo_cancel_reference_device(sound_stream_info_s *stream_info, int *device_id)
2515 SM_ARG_CHECK(stream_info);
2516 SM_ARG_CHECK(device_id);
2518 *device_id = stream_info->echo_cancel_reference_device;
2520 LOGI("stream_info[%p, %s] reference device_id[%d]",
2521 stream_info, stream_info->stream_type, *device_id);
2523 return SOUND_MANAGER_ERROR_NONE;
2526 int _set_rpi_playback_route(sound_rpi_playback_route_type type)
2530 LOGI("set rpi playback route : %u", type);
2532 ret = __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_SET_RPI_PLAYBACK_ROUTE, g_variant_new("(u)", type), NULL);
2533 if (ret != SOUND_MANAGER_ERROR_NONE)
2534 LOGE("_set_rpi_playback_route failed");
2539 int _get_rpi_playback_route(sound_rpi_playback_route_type *type)
2544 ret = vconf_get_int(VCONF_SOUND_RPI_PLAYBACK_ROUTE, &route_type);
2546 LOGE("Failed to get vconf [%s], err [%d]", VCONF_SOUND_RPI_PLAYBACK_ROUTE, ret);
2547 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2550 LOGI("current rpi playback route : %u", route_type);
2553 return SOUND_MANAGER_ERROR_NONE;
2558 static int __check_manual_route_type(sound_stream_info_s *stream_info)
2560 SM_ARG_CHECK(stream_info);
2562 if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL &&
2563 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL_EXT) {
2564 LOGE("route type is not manual or manual-ext");
2565 return SOUND_MANAGER_ERROR_POLICY;
2568 return SOUND_MANAGER_ERROR_NONE;
2571 static int __check_auto_route_type(sound_stream_info_s *stream_info)
2573 SM_ARG_CHECK(stream_info);
2575 if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO &&
2576 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
2577 LOGE("route type is not auto or auto-last-connected");
2578 return SOUND_MANAGER_ERROR_POLICY;
2581 return SOUND_MANAGER_ERROR_NONE;
2584 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)
2587 bool added_successfully = false;
2589 SM_ARG_CHECK(stream_info);
2590 SM_ARG_CHECK(device_type_str);
2592 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2593 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2594 if (!stream_info->stream_conf_info.avail_in_devices[i])
2596 if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2599 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2600 if (!stream_info->manual_route_info.route_in_devices[j]) {
2601 stream_info->manual_route_info.route_in_devices[j] = (unsigned int)device_id;
2602 added_successfully = true;
2605 if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
2606 LOGE("failed to add device, this IN/BOTH-device[type:%s, id:%d] has been already set", device_type_str, device_id);
2607 return SOUND_MANAGER_ERROR_POLICY;
2612 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2613 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2614 if (!stream_info->stream_conf_info.avail_out_devices[i])
2616 if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2619 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2620 if (!stream_info->manual_route_info.route_out_devices[j]) {
2621 stream_info->manual_route_info.route_out_devices[j] = (unsigned int)device_id;
2622 added_successfully = true;
2625 if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
2626 LOGE("failed to add device, this OUT/BOTH-device[type:%s, id:%d] has been already set", device_type_str, device_id);
2627 return SOUND_MANAGER_ERROR_POLICY;
2633 if (!added_successfully) {
2634 LOGE("failed to add device, not supported device[type:%s, id:%d]", device_type_str, device_id);
2635 return SOUND_MANAGER_ERROR_POLICY;
2638 return SOUND_MANAGER_ERROR_NONE;
2641 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)
2644 bool removed_successfully = false;
2646 SM_ARG_CHECK(stream_info);
2647 SM_ARG_CHECK(device_type_str);
2649 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2650 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2651 if (!stream_info->stream_conf_info.avail_in_devices[i])
2653 if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2656 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2657 if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
2658 removed_successfully = true;
2659 stream_info->manual_route_info.route_in_devices[j] = 0;
2665 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2666 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2667 if (!stream_info->stream_conf_info.avail_out_devices[i])
2669 if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2672 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2673 if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
2674 removed_successfully = true;
2675 stream_info->manual_route_info.route_out_devices[j] = 0;
2682 if (!removed_successfully) {
2683 LOGE("failed to remove device, could not find this device[type:%s, id:%d]", device_type_str, device_id);
2684 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
2687 return SOUND_MANAGER_ERROR_NONE;
2690 static int __is_available_device(sound_stream_info_s *stream_info, sound_device_h device, bool *available)
2692 int ret = SOUND_MANAGER_ERROR_NONE;
2693 int mm_ret = MM_ERROR_NONE;
2695 mm_sound_device_type_e mm_sound_device_type;
2696 sound_device_type_e device_type;
2697 char *device_type_str = NULL;
2698 char *avail_device_item = NULL;
2699 mm_sound_device_io_direction_e device_direction;
2702 SM_ARG_CHECK(stream_info);
2703 SM_ARG_CHECK(device);
2705 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE)
2706 return _convert_sound_manager_error_code(__func__, mm_ret);
2707 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)) != SOUND_MANAGER_ERROR_NONE)
2709 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2711 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)) != MM_ERROR_NONE)
2712 return _convert_sound_manager_error_code(__func__, mm_ret);
2714 if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_OUT) {
2715 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2716 if (!(avail_device_item = stream_info->stream_conf_info.avail_out_devices[i]))
2718 if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2722 LOGE("[OUT] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2724 return SOUND_MANAGER_ERROR_NONE;
2728 if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_IN) {
2730 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2731 if (!(avail_device_item = stream_info->stream_conf_info.avail_in_devices[i]))
2733 if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2737 LOGE("[IN] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2739 return SOUND_MANAGER_ERROR_NONE;
2745 return SOUND_MANAGER_ERROR_NONE;
2748 int _add_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2750 int ret = SOUND_MANAGER_ERROR_NONE;
2751 int mm_ret = MM_ERROR_NONE;
2752 char *device_type_str = NULL;
2754 mm_sound_device_type_e mm_sound_device_type;
2755 mm_sound_device_io_direction_e device_direction;
2756 sound_device_type_e device_type;
2758 SM_ARG_CHECK(stream_info);
2759 SM_ARG_CHECK(device);
2761 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
2764 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
2765 return _convert_sound_manager_error_code(__func__, mm_ret);
2766 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE)
2767 return _convert_sound_manager_error_code(__func__, mm_ret);
2768 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)) != SOUND_MANAGER_ERROR_NONE)
2770 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2772 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)) != MM_ERROR_NONE)
2773 return _convert_sound_manager_error_code(__func__, mm_ret);
2775 if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2778 LOGI("*** added device[type:%s, id:%d]", device_type_str, device_id);
2780 return SOUND_MANAGER_ERROR_NONE;
2783 int _remove_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2785 int ret = SOUND_MANAGER_ERROR_NONE;
2786 int mm_ret = MM_ERROR_NONE;
2787 char *device_type_str = NULL;
2789 mm_sound_device_type_e mm_sound_device_type;
2790 mm_sound_device_io_direction_e device_direction;
2791 sound_device_type_e device_type;
2793 SM_ARG_CHECK(stream_info);
2794 SM_ARG_CHECK(device);
2796 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
2799 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
2800 return _convert_sound_manager_error_code(__func__, mm_ret);
2801 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE)
2802 return _convert_sound_manager_error_code(__func__, mm_ret);
2803 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)) != SOUND_MANAGER_ERROR_NONE)
2805 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2807 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)) != MM_ERROR_NONE)
2808 return _convert_sound_manager_error_code(__func__, mm_ret);
2810 if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2813 LOGI("*** removed device[type:%s, id:%d]", device_type_str, device_id);
2815 return SOUND_MANAGER_ERROR_NONE;
2818 int _remove_all_devices_for_stream_routing(sound_stream_info_s *stream_info)
2820 int ret = SOUND_MANAGER_ERROR_NONE;
2823 SM_ARG_CHECK(stream_info);
2825 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
2828 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2829 stream_info->manual_route_info.route_in_devices[i] = 0;
2830 stream_info->manual_route_info.route_out_devices[i] = 0;
2833 stream_info->manual_route_info.is_set = false;
2835 LOGI("*** removed all devices");
2837 return SOUND_MANAGER_ERROR_NONE;
2840 int _add_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
2842 int ret = SOUND_MANAGER_ERROR_NONE;
2843 int mm_ret = MM_ERROR_NONE;
2844 char *device_type_str = NULL;
2845 mm_sound_device_type_e mm_sound_device_type;
2846 mm_sound_device_io_direction_e device_direction;
2847 sound_device_type_e device_type;
2848 MMSoundDevice_t device = NULL;
2850 SM_ARG_CHECK(stream_info);
2852 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
2855 if ((mm_ret = mm_sound_get_device_by_id(device_id, &device)) != MM_ERROR_NONE)
2856 return _convert_sound_manager_error_code(__func__, mm_ret);
2857 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE) {
2858 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2861 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)) != SOUND_MANAGER_ERROR_NONE)
2863 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2865 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)) != MM_ERROR_NONE) {
2866 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2870 if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2873 LOGI("*** added device by id[type:%s, id:%d]", device_type_str, device_id);
2877 mm_sound_free_device(device);
2881 int _remove_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
2883 int ret = SOUND_MANAGER_ERROR_NONE;
2884 int mm_ret = MM_ERROR_NONE;
2885 char *device_type_str = NULL;
2886 mm_sound_device_type_e mm_sound_device_type;
2887 mm_sound_device_io_direction_e device_direction;
2888 sound_device_type_e device_type;
2889 MMSoundDevice_t device = NULL;
2891 SM_ARG_CHECK(stream_info);
2893 if ((ret = __check_manual_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
2896 if ((mm_ret = mm_sound_get_device_by_id(device_id, &device)) != MM_ERROR_NONE)
2897 return _convert_sound_manager_error_code(__func__, mm_ret);
2898 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE) {
2899 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2902 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)) != SOUND_MANAGER_ERROR_NONE)
2904 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2906 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)) != MM_ERROR_NONE) {
2907 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2911 if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)) != SOUND_MANAGER_ERROR_NONE)
2914 LOGI("*** removed device by id[type:%s, id:%d]", device_type_str, device_id);
2918 mm_sound_free_device(device);
2922 int _apply_stream_routing(sound_stream_info_s *stream_info)
2926 SM_ARG_CHECK(stream_info);
2928 if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL &&
2929 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL_EXT) {
2930 LOGE("route type is not manual or manual-ext");//LCOV_EXCL_LINE
2931 /* Differ from others, it uses SOUND_INTERNAL error.
2932 * ACR process is required prior to changing error value. */
2933 return SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
2936 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2937 if (stream_info->manual_route_info.route_in_devices[i] ||
2938 stream_info->manual_route_info.route_out_devices[i])
2939 return _set_manual_route_info(stream_info->pa_info.index, &stream_info->manual_route_info);
2942 return SOUND_MANAGER_ERROR_INVALID_STATE;
2946 int _create_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream)
2948 bool result = false;
2949 const char *name = NULL;
2952 SM_ARG_CHECK(stream_info);
2953 SM_ARG_CHECK(virtual_stream);
2955 /* check if this stream_info is available for virtual stream */
2956 name = _convert_api_name(NATIVE_API_SOUND_MANAGER);
2957 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++) {
2958 if (stream_info->stream_conf_info.avail_frameworks[i] && !strncmp(stream_info->stream_conf_info.avail_frameworks[i], name, strlen(name))) {
2963 LOGI("stream_type[%s], native api[%s], is_available[%d]", stream_info->stream_type, name, result);
2965 return SOUND_MANAGER_ERROR_NOT_SUPPORTED;
2967 (*virtual_stream) = malloc(sizeof(virtual_sound_stream_info_s));
2968 if (!(*virtual_stream))
2969 return SOUND_MANAGER_ERROR_INTERNAL;
2971 memset((*virtual_stream), 0, sizeof(virtual_sound_stream_info_s));
2972 (*virtual_stream)->stream_type = stream_info->stream_type;
2973 (*virtual_stream)->pa_mainloop = stream_info->pa_info.mainloop;
2974 (*virtual_stream)->pa_context = stream_info->pa_info.context;
2975 (*virtual_stream)->pa_proplist = pa_proplist_new();
2976 pa_proplist_sets((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_ROLE, (*virtual_stream)->stream_type);
2977 pa_proplist_setf((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_PARENT_ID, "%u", stream_info->pa_info.index);
2978 (*virtual_stream)->state = _VSTREAM_STATE_READY;
2979 (*virtual_stream)->stream_info = stream_info;
2981 return SOUND_MANAGER_ERROR_NONE;
2984 int _destroy_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2986 SM_ARG_CHECK(virtual_stream);
2987 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_READY);
2989 virtual_stream->pa_mainloop = NULL;
2990 virtual_stream->pa_context = NULL;
2991 if (virtual_stream->pa_proplist)
2992 pa_proplist_free(virtual_stream->pa_proplist);
2994 virtual_stream->stream_info->vstream = NULL;
2996 SM_SAFE_FREE(virtual_stream);
2998 return SOUND_MANAGER_ERROR_NONE;
3001 int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
3003 int ret = SOUND_MANAGER_ERROR_NONE;
3006 int io_direction = 0;
3008 pa_channel_map maps;
3010 SM_ARG_CHECK(virtual_stream);
3011 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_READY);
3013 /* fill up with default value */
3016 ss.format = PA_SAMPLE_S16LE;
3017 pa_channel_map_init_auto(&maps, ss.channels, PA_CHANNEL_MAP_ALSA);
3019 /* check direction of this stream */
3020 if (virtual_stream->stream_info->stream_conf_info.avail_in_devices[0] != NULL)
3021 io_direction |= SOUND_STREAM_DIRECTION_INPUT;
3022 if (virtual_stream->stream_info->stream_conf_info.avail_out_devices[0] != NULL)
3023 io_direction |= SOUND_STREAM_DIRECTION_OUTPUT;
3025 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
3027 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
3028 if (io_direction & (i + 1)) {
3029 virtual_stream->pa_stream[i] = pa_stream_new_with_proplist(virtual_stream->pa_context, "VIRTUAL_STREAM", &ss, &maps, virtual_stream->pa_proplist);
3030 if (virtual_stream->pa_stream[i] == NULL) {
3031 LOGE("failed to pa_stream_new_with_proplist()");
3032 pa_ret = pa_context_errno(virtual_stream->pa_context);
3033 ret = SOUND_MANAGER_ERROR_INTERNAL;
3034 goto ERROR_WITH_UNLOCK;
3036 pa_stream_set_state_callback(virtual_stream->pa_stream[i], _pa_stream_state_cb, virtual_stream);
3038 if ((i + 1) == SOUND_STREAM_DIRECTION_OUTPUT) {
3039 pa_ret = pa_stream_connect_playback(virtual_stream->pa_stream[i], NULL, NULL, 0, NULL, NULL);
3041 LOGE("failed to pa_stream_connect_playback()");
3042 pa_ret = pa_context_errno(virtual_stream->pa_context);
3043 ret = SOUND_MANAGER_ERROR_INTERNAL;
3044 goto ERROR_WITH_UNLOCK;
3046 } else if ((i + 1) == SOUND_STREAM_DIRECTION_INPUT) {
3047 pa_ret = pa_stream_connect_record(virtual_stream->pa_stream[i], NULL, NULL, 0);
3049 LOGE("failed to pa_stream_connect_record()");
3050 pa_ret = pa_context_errno(virtual_stream->pa_context);
3051 ret = SOUND_MANAGER_ERROR_INTERNAL;
3052 goto ERROR_WITH_UNLOCK;
3056 /* wait for ready state of the stream */
3058 pa_stream_state_t state;
3059 state = pa_stream_get_state(virtual_stream->pa_stream[i]);
3060 if (state == PA_STREAM_READY)
3062 if (!PA_STREAM_IS_GOOD(state)) {
3063 LOGE("stream(%d) is not good, state : %d", i, state);
3064 pa_ret = pa_context_errno(virtual_stream->pa_context);
3065 ret = SOUND_MANAGER_ERROR_INTERNAL;
3066 goto ERROR_WITH_UNLOCK;
3069 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
3073 virtual_stream->state = _VSTREAM_STATE_RUNNING;
3075 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
3077 return SOUND_MANAGER_ERROR_NONE;
3080 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
3082 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
3083 if (virtual_stream->pa_stream[i]) {
3084 pa_stream_unref(virtual_stream->pa_stream[i]);
3085 virtual_stream->pa_stream[i] = NULL;
3088 LOGE("pa_ret(%d)", pa_ret);
3092 int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
3097 SM_ARG_CHECK(virtual_stream);
3098 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_RUNNING);
3100 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
3102 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
3103 if (!virtual_stream->pa_stream[i])
3106 LOGI("[%d] disconnecting vstream_h[%p] index[%d] state[%d]",
3107 i, virtual_stream, pa_stream_get_index(virtual_stream->pa_stream[i]), pa_stream_get_state(virtual_stream->pa_stream[i]));
3109 ret = pa_stream_disconnect(virtual_stream->pa_stream[i]);
3111 /* wait for terminated state of the stream */
3113 pa_stream_state_t state = pa_stream_get_state(virtual_stream->pa_stream[i]);
3114 if (state == PA_STREAM_TERMINATED)
3116 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
3119 LOGE("[%d] disconnection failed for vstream_h[%p] index[%d], ret[%d][%s]",
3120 i, virtual_stream, pa_stream_get_index(virtual_stream->pa_stream[i]), ret, pa_strerror(ret));
3123 pa_stream_unref(virtual_stream->pa_stream[i]);
3124 virtual_stream->pa_stream[i] = NULL;
3127 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
3129 virtual_stream->state = _VSTREAM_STATE_READY;
3131 return SOUND_MANAGER_ERROR_NONE;
3134 int _set_volume_ratio(uint32_t stream_index, sound_stream_direction_e direction, double ratio)
3136 int ret = SOUND_MANAGER_ERROR_NONE;
3137 GDBusConnection *conn = NULL;
3139 GVariant *result = NULL;
3140 const gchar *dbus_ret = NULL;
3142 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3145 result = g_dbus_connection_call_sync(conn,
3147 PA_STREAM_MANAGER_OBJECT_PATH,
3148 PA_STREAM_MANAGER_INTERFACE,
3149 PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATIO,
3150 g_variant_new("(sud)", (direction == SOUND_STREAM_DIRECTION_OUTPUT) ? "out" : "in", stream_index, ratio),
3151 G_VARIANT_TYPE("(s)"),
3152 G_DBUS_CALL_FLAGS_NONE,
3153 DBUS_METHOD_TIMEOUT,
3156 if (!result || err) {
3157 LOGE("g_dbus_connection_call_sync() for SET_VOLUME_RATIO error (%s)", err ? err->message : NULL);
3158 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3164 g_variant_get(result, "(&s)", &dbus_ret);
3166 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret)))
3167 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3168 else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
3169 ret = SOUND_MANAGER_ERROR_NO_DATA;
3170 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3171 ret = SOUND_MANAGER_ERROR_INTERNAL;
3173 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3177 g_variant_unref(result);
3178 g_object_unref(conn);
3183 int _set_virtual_stream_volume(virtual_sound_stream_info_s *virtual_stream, double ratio)
3185 int ret = SOUND_MANAGER_ERROR_NONE;
3189 SM_ARG_CHECK(virtual_stream);
3190 SM_STATE_CHECK(virtual_stream, _VSTREAM_STATE_RUNNING);
3192 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
3194 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
3195 if (virtual_stream->pa_stream[i]) {
3196 index = pa_stream_get_index(virtual_stream->pa_stream[i]);
3197 if ((ret = _set_volume_ratio(index, i + 1, ratio)) != SOUND_MANAGER_ERROR_NONE) {
3198 if (ret == SOUND_MANAGER_ERROR_NO_DATA) {
3199 LOGE("something wrong, no match index of %u", index);
3200 ret = SOUND_MANAGER_ERROR_INTERNAL;
3207 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
3212 int _set_acm_master_mode(bool on)
3214 int ret = SOUND_MANAGER_ERROR_NONE;
3215 GVariant *result = NULL;
3216 GDBusConnection *conn = NULL;
3219 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3222 result = g_dbus_connection_call_sync(conn,
3224 PA_DEVICE_MANAGER_OBJECT_PATH,
3225 PA_DEVICE_MANAGER_INTERFACE,
3226 PA_DEVICE_MANAGER_METHOD_NAME_SET_ACM_MODE,
3227 g_variant_new("(u)", (unsigned int)on),
3229 G_DBUS_CALL_FLAGS_NONE,
3230 DBUS_METHOD_TIMEOUT,
3234 LOGE("g_dbus_connection_call_sync() for SET ACM MODE error (%s)", err->message);
3235 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
3239 LOGI("ACM master mode [%s]", on ? "ON" : "OFF");
3244 g_variant_unref(result);
3245 g_object_unref(conn);
3250 int _activate_ducking(uint32_t stream_index, bool enable, const char *target_stream, uint32_t duration, double ratio)
3252 int ret = SOUND_MANAGER_ERROR_NONE;
3253 GDBusConnection *conn = NULL;
3255 GVariant *result = NULL;
3256 const gchar *dbus_ret = NULL;
3258 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3261 result = g_dbus_connection_call_sync(conn,
3263 PA_STREAM_MANAGER_OBJECT_PATH,
3264 PA_STREAM_MANAGER_INTERFACE,
3265 PA_STREAM_MANAGER_METHOD_NAME_ACTIVATE_DUCKING,
3266 g_variant_new("(ubsud)", stream_index, enable, target_stream, duration, ratio),
3267 G_VARIANT_TYPE("(s)"),
3268 G_DBUS_CALL_FLAGS_NONE,
3269 DBUS_METHOD_TIMEOUT,
3272 if (!result || err) {
3273 LOGE("g_dbus_connection_call_sync() for ACTIVATE_DUCKING error");
3274 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3280 g_variant_get(result, "(&s)", &dbus_ret);
3281 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_INVALID_STATE", dbus_ret, strlen(dbus_ret)))
3282 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
3283 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3284 ret = SOUND_MANAGER_ERROR_INTERNAL;
3286 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3290 g_variant_unref(result);
3291 g_object_unref(conn);
3296 int _get_ducking_state(sound_pa_info_s *pa_info, bool *is_ducked)
3298 int ret = SOUND_MANAGER_ERROR_NONE;
3299 gboolean _is_ducked = FALSE;
3300 GDBusConnection *conn = NULL;
3302 GVariant *result = NULL;
3303 const gchar *dbus_ret = NULL;
3305 SM_ARG_CHECK(pa_info);
3306 SM_ARG_CHECK(is_ducked);
3308 if (pa_info->is_disconnected) {
3309 LOGE("server disconnected");
3310 return SOUND_MANAGER_ERROR_INTERNAL;
3313 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3316 result = g_dbus_connection_call_sync(conn,
3318 PA_STREAM_MANAGER_OBJECT_PATH,
3319 PA_STREAM_MANAGER_INTERFACE,
3320 PA_STREAM_MANAGER_METHOD_NAME_GET_DUCKING_STATE,
3321 g_variant_new("(u)", pa_info->index),
3322 G_VARIANT_TYPE("(bs)"),
3323 G_DBUS_CALL_FLAGS_NONE,
3324 DBUS_METHOD_TIMEOUT,
3327 if (!result || err) {
3328 LOGE("g_dbus_connection_call_sync() for GET_DUCKING_STATE error");
3329 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3335 g_variant_get(result, "(b&s)", &_is_ducked, &dbus_ret);
3337 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3338 *is_ducked = (bool)_is_ducked;
3339 LOGI("is_ducked[%d]", *is_ducked);
3341 ret = SOUND_MANAGER_ERROR_INTERNAL;
3344 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3348 g_variant_unref(result);
3349 g_object_unref(conn);
3354 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)
3356 int ret = SOUND_MANAGER_ERROR_NONE;
3357 GVariant *result = NULL;
3358 GDBusConnection *conn = NULL;
3360 const gchar *dbus_ret = NULL;
3361 const gchar *direction_str;
3364 SM_ARG_CHECK(stream_info);
3366 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3369 for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
3371 if (!(io_direction & (i + 1)))
3374 if (!((req_direction + 1) & (i + 1)))
3377 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3379 result = g_dbus_connection_call_sync(conn,
3381 PA_STREAM_MANAGER_OBJECT_PATH,
3382 PA_STREAM_MANAGER_INTERFACE,
3383 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE,
3384 g_variant_new("(usu)", stream_info->pa_info.index, direction_str, (unsigned int)device_id),
3386 G_DBUS_CALL_FLAGS_NONE,
3387 DBUS_METHOD_TIMEOUT,
3390 if (!result || err) {
3391 LOGE("g_dbus_connection_call_sync() for SET PREFERRED DEVICE error (%s)", err ? err->message : NULL);
3392 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3398 LOGI("Preferred device(id:%d, direction:%s) is set to PA context(%u)", device_id, direction_str, stream_info->pa_info.index);
3400 g_variant_get(result, "(&s)", &dbus_ret);
3402 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_DEVICE_NOT_FOUND", dbus_ret, strlen(dbus_ret)))
3403 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3404 else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
3405 ret = SOUND_MANAGER_ERROR_POLICY;
3406 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3407 ret = SOUND_MANAGER_ERROR_INTERNAL;
3409 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3414 if (i == SOUND_DEVICE_IO_DIRECTION_IN)
3415 stream_info->preferred_device_info.in = device_id;
3417 stream_info->preferred_device_info.out = device_id;
3422 g_variant_unref(result);
3423 g_object_unref(conn);
3428 int _set_preferred_device(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, sound_device_h device)
3430 int ret = SOUND_MANAGER_ERROR_NONE;
3431 int mm_ret = MM_ERROR_NONE;
3432 bool available = false;
3434 mm_sound_device_io_direction_e io_direction = MM_SOUND_DEVICE_IO_DIRECTION_IN;
3436 SM_ARG_CHECK(stream_info);
3438 /* allow only auto route type */
3439 if ((ret = __check_auto_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
3442 /* check if this device belongs to available devices of the stream info */
3443 /* In case device is null, it's for unsetting preferred device, device_id will be 0. */
3445 if ((ret = __is_available_device(stream_info, device, &available)) != SOUND_MANAGER_ERROR_NONE)
3448 return SOUND_MANAGER_ERROR_POLICY;
3449 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
3450 return _convert_sound_manager_error_code(__func__, mm_ret);
3451 if ((mm_ret = mm_sound_get_device_io_direction(device, &io_direction)) != MM_ERROR_NONE)
3452 return _convert_sound_manager_error_code(__func__, mm_ret);
3453 if (!(io_direction & (direction + 1)) || ((int)io_direction < (int)(direction + 1))) {
3454 LOGE("device direction(0x%x), request direction(0x%x)", io_direction, (direction + 1));
3455 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3459 return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3462 int _set_preferred_device_id(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, int device_id)
3464 int ret = SOUND_MANAGER_ERROR_NONE;
3465 int mm_ret = MM_ERROR_NONE;
3466 bool available = false;
3467 mm_sound_device_io_direction_e io_direction = MM_SOUND_DEVICE_IO_DIRECTION_IN;
3469 SM_ARG_CHECK(stream_info);
3471 /* allow only auto route type */
3472 if ((ret = __check_auto_route_type(stream_info)) != SOUND_MANAGER_ERROR_NONE)
3475 /* check if this device belongs to available devices of the stream info */
3476 /* In case device_id is 0, it's for unsetting preferred device. */
3478 MMSoundDevice_t device = NULL;
3480 if ((mm_ret = mm_sound_get_device_by_id(device_id, &device)) != MM_ERROR_NONE) {
3481 LOGE("failed to mm_sound_get_device_by_id()");
3482 return _convert_sound_manager_error_code(__func__, mm_ret);
3484 if ((ret = __is_available_device(stream_info, (sound_device_h)device, &available)) != SOUND_MANAGER_ERROR_NONE)
3487 ret = SOUND_MANAGER_ERROR_POLICY;
3490 if ((mm_ret = mm_sound_get_device_io_direction(device, &io_direction)) != MM_ERROR_NONE) {
3491 ret = _convert_sound_manager_error_code(__func__, mm_ret);
3494 if (!(io_direction & (direction + 1)) || ((int)io_direction < (int)(direction + 1))) {
3495 LOGE("device direction(0x%x), request direction(0x%x)", io_direction, (direction + 1));
3496 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3499 mm_sound_free_device(device);
3504 return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3507 int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id)
3509 int ret = SOUND_MANAGER_ERROR_NONE;
3510 GDBusConnection *conn = NULL;
3512 GVariant *result = NULL;
3513 const gchar *dbus_ret = NULL;
3514 unsigned int _in_device_id;
3515 unsigned int _out_device_id;
3517 SM_ARG_CHECK(stream_info);
3519 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3522 result = g_dbus_connection_call_sync(conn,
3524 PA_STREAM_MANAGER_OBJECT_PATH,
3525 PA_STREAM_MANAGER_INTERFACE,
3526 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE,
3527 g_variant_new("(u)", stream_info->pa_info.index),
3528 G_VARIANT_TYPE("(uus)"),
3529 G_DBUS_CALL_FLAGS_NONE,
3530 DBUS_METHOD_TIMEOUT,
3533 if (!result || err) {
3534 LOGE("g_dbus_connection_call_sync() for GET_STREAM_PREFERRED_DEVICE error");
3535 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3541 g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3543 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3545 if (stream_info->preferred_device_info.in != _in_device_id) {
3546 LOGE("mismatching id [prev: %d, curr: %d]", stream_info->preferred_device_info.in, _in_device_id);
3547 ret = SOUND_MANAGER_ERROR_INTERNAL;
3549 *in_device_id = _in_device_id;
3550 LOGI("preferred device id[in:%d]", *in_device_id);
3553 if (out_device_id) {
3554 if (stream_info->preferred_device_info.out != _out_device_id) {
3555 LOGE("mismatching id [prev: %d, curr: %d]", stream_info->preferred_device_info.out, _out_device_id);
3556 ret = SOUND_MANAGER_ERROR_INTERNAL;
3558 *out_device_id = _out_device_id;
3559 LOGI("preferred device id[out:%d]", *out_device_id);
3563 ret = SOUND_MANAGER_ERROR_INTERNAL;
3566 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3570 g_variant_unref(result);
3571 g_object_unref(conn);
3576 static int __invoke_ipc_set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e io_direction, int device_id)
3578 int ret = SOUND_MANAGER_ERROR_NONE;
3579 GVariant *result = NULL;
3580 GDBusConnection *conn = NULL;
3582 const gchar *dbus_ret = NULL;
3583 const gchar *direction_str;
3584 char *stream_type_str;
3587 if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != SOUND_MANAGER_ERROR_NONE)
3590 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3593 for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
3594 if (io_direction != SOUND_DEVICE_IO_DIRECTION_BOTH && io_direction != i)
3596 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3598 result = g_dbus_connection_call_sync(conn,
3600 PA_STREAM_MANAGER_OBJECT_PATH,
3601 PA_STREAM_MANAGER_INTERFACE,
3602 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREEMPTIVE_DEVICE,
3603 g_variant_new("(ssu)", stream_type_str, direction_str, (unsigned int)device_id),
3605 G_DBUS_CALL_FLAGS_NONE,
3606 DBUS_METHOD_TIMEOUT,
3609 if (!result || err) {
3610 LOGE("g_dbus_connection_call_sync() for SET_STREAM_PREEMPTIVE_DEVICE, direction(%s) error (%s)",
3611 direction_str, err ? err->message : NULL);
3612 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3616 g_variant_unref(result);
3622 LOGI("Preemptive device(id:%d, direction:%s) is set", device_id, direction_str);
3624 g_variant_get(result, "(&s)", &dbus_ret);
3626 if (!strncmp("STREAM_MANAGER_RETURN_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret)))
3627 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3628 else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
3629 ret = SOUND_MANAGER_ERROR_POLICY;
3630 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3631 ret = SOUND_MANAGER_ERROR_INTERNAL;
3633 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3641 g_variant_unref(result);
3642 g_object_unref(conn);
3647 static int __invoke_ipc_get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3649 int ret = SOUND_MANAGER_ERROR_NONE;
3650 GDBusConnection *conn = NULL;
3652 GVariant *result = NULL;
3653 const gchar *dbus_ret = NULL;
3654 unsigned int _in_device_id;
3655 unsigned int _out_device_id;
3656 char *stream_type_str;
3658 if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != SOUND_MANAGER_ERROR_NONE)
3661 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3664 result = g_dbus_connection_call_sync(conn,
3666 PA_STREAM_MANAGER_OBJECT_PATH,
3667 PA_STREAM_MANAGER_INTERFACE,
3668 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREEMPTIVE_DEVICE,
3669 g_variant_new("(s)", stream_type_str),
3670 G_VARIANT_TYPE("(uus)"),
3671 G_DBUS_CALL_FLAGS_NONE,
3672 DBUS_METHOD_TIMEOUT,
3675 if (!result || err) {
3676 LOGE("g_dbus_connection_call_sync() for GET_STREAM_PREEMPTIVE_DEVICE error");
3677 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3682 g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3684 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3686 *in_device_id = _in_device_id;
3687 LOGI("preemptive device id[in:%d]", *in_device_id);
3689 if (out_device_id) {
3690 *out_device_id = _out_device_id;
3691 LOGI("preemptive device id[out:%d]", *out_device_id);
3694 ret = SOUND_MANAGER_ERROR_INTERNAL;
3697 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3701 g_variant_unref(result);
3702 g_object_unref(conn);
3707 int _set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id)
3709 return __invoke_ipc_set_preemptive_device(stream_type, direction, device_id);
3712 int _get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3714 return __invoke_ipc_get_preemptive_device(stream_type, in_device_id, out_device_id);
3717 int _get_latest_stream_pid(int stream_type, unsigned int *pid)
3719 int ret = SOUND_MANAGER_ERROR_NONE;
3720 GDBusConnection *conn = NULL;
3722 GVariant *result = NULL;
3723 GVariantBuilder *builder_for_stream_types;
3724 const gchar *dbus_ret = NULL;
3729 if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE)
3732 builder_for_stream_types = g_variant_builder_new(G_VARIANT_TYPE("as"));
3733 if (!builder_for_stream_types) {
3734 LOGE("failed to g_variant_builder_new()");
3735 ret = SOUND_MANAGER_ERROR_INTERNAL;
3739 if (stream_type & STREAM_TYPE_MEDIA)
3740 g_variant_builder_add(builder_for_stream_types, "s", STREAM_MEDIA);
3741 if (stream_type & STREAM_TYPE_SYSTEM)
3742 g_variant_builder_add(builder_for_stream_types, "s", STREAM_SYSTEM);
3743 if (stream_type & STREAM_TYPE_ALARM)
3744 g_variant_builder_add(builder_for_stream_types, "s", STREAM_ALARM);
3745 if (stream_type & STREAM_TYPE_NOTIFICATION)
3746 g_variant_builder_add(builder_for_stream_types, "s", STREAM_NOTIFICATION);
3747 if (stream_type & STREAM_TYPE_EMERGENCY)
3748 g_variant_builder_add(builder_for_stream_types, "s", STREAM_EMERGENCY);
3749 if (stream_type & STREAM_TYPE_VOICE_INFORMATION)
3750 g_variant_builder_add(builder_for_stream_types, "s", STREAM_VOICE_INFORMATION);
3752 result = g_dbus_connection_call_sync(conn,
3754 PA_STREAM_MANAGER_OBJECT_PATH,
3755 PA_STREAM_MANAGER_INTERFACE,
3756 PA_STREAM_MANAGER_METHOD_NAME_GET_LASTEST_STREAM_PID,
3757 g_variant_new("(sas)", "out", builder_for_stream_types),
3758 G_VARIANT_TYPE("(us)"),
3759 G_DBUS_CALL_FLAGS_NONE,
3760 DBUS_METHOD_TIMEOUT,
3763 if (!result || err) {
3764 LOGE("g_dbus_connection_call_sync() for GET_LASTEST_STREAM_PID error");
3765 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3771 g_variant_get(result, "(u&s)", &_pid, &dbus_ret);
3773 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3775 else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
3776 ret = SOUND_MANAGER_ERROR_NO_DATA;
3778 ret = SOUND_MANAGER_ERROR_INTERNAL;
3780 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3783 if (builder_for_stream_types)
3784 g_variant_builder_unref(builder_for_stream_types);
3786 g_variant_unref(result);
3787 g_object_unref(conn);
3792 #define CONTAINER_FILE "/run/systemd/container"
3793 #define DBUS_HOST_SYSTEM_BUS_ADDRESS "unix:path=/run/host/dbus/system_bus_socket"
3795 static GDBusConnection * __get_host_dbus_connection()
3797 GDBusConnection *conn = NULL;
3799 g_autoptr(GError) err = NULL;
3801 if (access(CONTAINER_FILE, F_OK) != 0) {
3802 LOGE("Not in container....");
3806 conn = g_dbus_connection_new_for_address_sync(DBUS_HOST_SYSTEM_BUS_ADDRESS,
3807 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
3810 LOGE("g_dbus_connection_new_for_address_sync() error (%s)", err ? err->message : "(null)");
3815 int _set_host_volume_level(const char *direction, const char *volume_type, unsigned int level)
3817 int ret = SOUND_MANAGER_ERROR_NONE;
3818 const gchar *dbus_ret = NULL;
3820 g_autoptr(GVariant) result = NULL;
3821 g_autoptr(GDBusConnection) conn = NULL;
3822 g_autoptr(GError) err = NULL;
3824 SM_ARG_CHECK(direction);
3825 SM_ARG_CHECK(volume_type);
3827 if (!(conn = __get_host_dbus_connection()))
3828 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
3830 result = g_dbus_connection_call_sync(conn,
3832 PA_STREAM_MANAGER_OBJECT_PATH,
3833 PA_STREAM_MANAGER_INTERFACE,
3834 PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL,
3835 g_variant_new("(ssu)", direction, volume_type, level),
3836 G_VARIANT_TYPE("(s)"),
3837 G_DBUS_CALL_FLAGS_NONE,
3838 DBUS_METHOD_TIMEOUT,
3842 return _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3844 g_variant_get(result, "(&s)", &dbus_ret);
3846 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3847 ret = SOUND_MANAGER_ERROR_INTERNAL;
3849 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);
3854 int _get_host_volume_level(const char *direction, const char *volume_type, unsigned int *level)
3856 int ret = SOUND_MANAGER_ERROR_NONE;
3857 const gchar *dbus_ret = NULL;
3859 g_autoptr(GVariant) result = NULL;
3860 g_autoptr(GDBusConnection) conn = NULL;
3861 g_autoptr(GError) err = NULL;
3863 SM_ARG_CHECK(direction);
3864 SM_ARG_CHECK(volume_type);
3865 SM_ARG_CHECK(level);
3867 if (!(conn = __get_host_dbus_connection()))
3868 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
3870 result = g_dbus_connection_call_sync(conn,
3872 PA_STREAM_MANAGER_OBJECT_PATH,
3873 PA_STREAM_MANAGER_INTERFACE,
3874 PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL,
3875 g_variant_new("(ss)", direction, volume_type),
3876 G_VARIANT_TYPE("(us)"),
3877 G_DBUS_CALL_FLAGS_NONE,
3878 DBUS_METHOD_TIMEOUT,
3882 return _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3884 g_variant_get(result, "(u&s)", level, &dbus_ret);
3886 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3887 ret = SOUND_MANAGER_ERROR_INTERNAL;
3889 LOGI("level[%u]", *level);
3891 LOGI("dbus_ret[%s] ret[0x%x]", dbus_ret, ret);