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 2000
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"
69 #define PA_DEVICE_MANAGER_OBJECT_PATH "/org/pulseaudio/DeviceManager"
70 #define PA_DEVICE_MANAGER_INTERFACE "org.pulseaudio.DeviceManager"
71 #define PA_DEVICE_MANAGER_METHOD_NAME_IS_DEVICE_RUNNING_BY_ID "IsDeviceRunningById"
72 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_FORMATS "GetSupportedSampleFormats"
73 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_FORMAT "SetSampleFormat"
74 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_FORMAT "GetSampleFormat"
75 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_RATES "GetSupportedSampleRates"
76 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_RATE "SetSampleRate"
77 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_RATE "GetSampleRate"
78 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_AVOID_RESAMPLING "SetAvoidResampling"
79 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_AVOID_RESAMPLING "GetAvoidResampling"
80 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_SPECIFIC_STREAM "SetSpecificStreamOnly"
81 #define PA_DEVICE_MANAGER_METHOD_NAME_GET_SPECIFIED_STREAM "GetSpecifiedStream"
82 #define PA_DEVICE_MANAGER_METHOD_NAME_SET_ACM_MODE "SetAcmMode"
84 #define VCONF_PATH_PREFIX_VOLUME "file/private/sound/volume/"
85 #define VCONF_PATH_MAX 64
87 #define SM_SOUND_TYPE_CHECK(x_sound_type, x_error) \
88 if (!strncmp(x_sound_type, "system", strlen(x_sound_type)) || \
89 !strncmp(x_sound_type, "notification", strlen(x_sound_type)) || \
90 !strncmp(x_sound_type, "alarm", strlen(x_sound_type)) || \
91 !strncmp(x_sound_type, "ringtone", strlen(x_sound_type)) || \
92 !strncmp(x_sound_type, "media", strlen(x_sound_type)) || \
93 !strncmp(x_sound_type, "call", strlen(x_sound_type)) || \
94 !strncmp(x_sound_type, "voip", strlen(x_sound_type)) || \
95 !strncmp(x_sound_type, "voice", strlen(x_sound_type))) \
98 #define SM_INTERNAL_SOUND_TYPE_CHECK(x_sound_type, x_error) \
99 if (!strncmp(x_sound_type, "bixby", strlen(x_sound_type))) \
103 int _convert_dbus_error(const char *error_msg)
105 int ret = MM_ERROR_NONE;
108 return MM_ERROR_SOUND_INTERNAL;
110 if (strstr(error_msg, "InvalidArgument"))
111 ret = MM_ERROR_INVALID_ARGUMENT;
112 else if (strstr(error_msg, "InvalidOperation"))
113 ret = MM_ERROR_SOUND_INVALID_OPERATION;
114 else if (strstr(error_msg, "PolicyInternal"))
115 ret = MM_ERROR_POLICY_INTERNAL;
116 else if (strstr(error_msg, "AccessDenied"))
117 ret = MM_ERROR_SOUND_PERMISSION_DENIED;
119 ret = MM_ERROR_SOUND_INTERNAL;
121 LOGE("%s => 0x%x", error_msg, ret);
127 int _convert_sound_manager_error_code(const char *func, int code)
129 int ret = SOUND_MANAGER_ERROR_NONE;
130 char *errorstr = NULL;
133 case MM_ERROR_FILE_WRITE:
134 case MM_ERROR_INVALID_HANDLE:
135 case MM_ERROR_SOUND_INVALID_OPERATION:
136 ret = SOUND_MANAGER_ERROR_INVALID_OPERATION;
137 errorstr = "INVALID_OPERATION";
140 ret = SOUND_MANAGER_ERROR_NONE;
141 errorstr = "ERROR_NONE";
143 case MM_ERROR_INVALID_ARGUMENT:
144 case MM_ERROR_SOUND_INVALID_POINTER:
145 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
146 errorstr = "INVALID_PARAMETER";
148 case MM_ERROR_SOUND_PERMISSION_DENIED:
150 ret = SOUND_MANAGER_ERROR_PERMISSION_DENIED;
151 errorstr = "PERMISSION_DENIED";
154 case MM_ERROR_SOUND_NO_DATA:
155 ret = SOUND_MANAGER_ERROR_NO_DATA;
156 errorstr = "NO_DATA";
158 case MM_ERROR_SOUND_INTERNAL:
159 case MM_ERROR_SOUND_VOLUME_CAPTURE_ONLY:
160 case MM_ERROR_OUT_OF_MEMORY:
161 case MM_ERROR_SOUND_SERVER_DISCONNECTED:
163 ret = SOUND_MANAGER_ERROR_INTERNAL;
164 errorstr = "INTERNAL";
167 case MM_ERROR_POLICY_DUPLICATED:
168 case MM_ERROR_POLICY_INTERNAL:
169 case MM_ERROR_POLICY_BLOCKED:
170 ret = SOUND_MANAGER_ERROR_POLICY;
173 case MM_ERROR_SOUND_VOLUME_NO_INSTANCE:
174 ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
175 errorstr = "NO_PLAYING_SOUND";
177 case MM_ERROR_NOT_SUPPORT_API:
178 ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
179 errorstr = "NOT_SUPPORTED";
181 case MM_ERROR_SOUND_INVALID_STATE:
182 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
183 errorstr = "INVALID_STATE";
187 LOGW("it should not be reached here, this error(0x%x) should be defined.", code);
188 ret = SOUND_MANAGER_ERROR_INTERNAL;
189 errorstr = "INTERNAL";
194 LOGE("[%s] >> leave : %s(0x%08x), mm_error(0x%08x)", func, errorstr, ret, code);
196 LOGD("[%s] >> leave : %s(0x%08x)", func, errorstr, ret);
201 int _convert_stream_type(sound_stream_type_e stream_type_enum, char **stream_type)
203 SM_ARG_CHECK(stream_type);
205 switch (stream_type_enum) {
206 case SOUND_STREAM_TYPE_MEDIA:
207 *stream_type = STREAM_MEDIA;
209 case SOUND_STREAM_TYPE_SYSTEM:
210 *stream_type = STREAM_SYSTEM;
212 case SOUND_STREAM_TYPE_ALARM:
213 *stream_type = STREAM_ALARM;
215 case SOUND_STREAM_TYPE_NOTIFICATION:
216 *stream_type = STREAM_NOTIFICATION;
218 case SOUND_STREAM_TYPE_EMERGENCY:
219 *stream_type = STREAM_EMERGENCY;
221 case SOUND_STREAM_TYPE_VOICE_INFORMATION:
222 *stream_type = STREAM_VOICE_INFORMATION;
224 case SOUND_STREAM_TYPE_VOICE_RECOGNITION:
225 *stream_type = STREAM_VOICE_RECOGNITION;
227 case SOUND_STREAM_TYPE_RINGTONE_VOIP:
228 *stream_type = STREAM_RINGTONE_VOIP;
230 case SOUND_STREAM_TYPE_VOIP:
231 *stream_type = STREAM_VOIP;
233 case SOUND_STREAM_TYPE_MEDIA_EXTERNAL_ONLY:
234 *stream_type = STREAM_EXT_MEDIA;
238 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
239 return SOUND_MANAGER_ERROR_INTERNAL;
243 LOGI("stream_type[%s]", *stream_type);
245 return SOUND_MANAGER_ERROR_NONE;
249 int _convert_stream_type_for_internal(sound_stream_type_internal_e stream_type_enum, char **stream_type)
251 SM_ARG_CHECK(stream_type);
253 switch (stream_type_enum) {
254 case SOUND_STREAM_TYPE_RINGTONE_CALL:
255 *stream_type = STREAM_RINGTONE_CALL;
257 case SOUND_STREAM_TYPE_RINGBACKTONE_CALL:
258 *stream_type = STREAM_RINGBACKTONE_CALL;
260 case SOUND_STREAM_TYPE_VOICE_CALL:
261 *stream_type = STREAM_CALL_VOICE;
263 case SOUND_STREAM_TYPE_VIDEO_CALL:
264 *stream_type = STREAM_CALL_VIDEO;
266 case SOUND_STREAM_TYPE_RADIO:
267 *stream_type = STREAM_RADIO;
269 case SOUND_STREAM_TYPE_LOOPBACK:
270 *stream_type = STREAM_LOOPBACK;
272 case SOUND_STREAM_TYPE_LOOPBACK_MIRRORING:
273 *stream_type = STREAM_LOOPBACK_MIRRORING;
275 case SOUND_STREAM_TYPE_SOLO:
276 *stream_type = STREAM_SOLO;
278 case SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE:
279 *stream_type = STREAM_VOICE_RECOGNITION_SERVICE;
281 case SOUND_STREAM_TYPE_MEDIA_COMPRESSED:
282 *stream_type = STREAM_COMPRESSED_MEDIA;
284 #ifndef TIZEN_FEATURE_TV_PROD
285 case SOUND_STREAM_TYPE_MEDIA_NETWORK_SOURCE:
286 *stream_type = STREAM_NETWORK_SOURCE_MEDIA;
290 LOGE("could not find the stream_type[%d] in this switch case statement", stream_type_enum);
291 return SOUND_MANAGER_ERROR_INTERNAL;
293 LOGI("stream_type_for_internal[%s]", *stream_type);
295 return SOUND_MANAGER_ERROR_NONE;
298 void _set_focus_availability(sound_stream_info_s *stream_info)
300 if (stream_info == NULL || stream_info->stream_type == NULL) {
301 LOGE("invalid argument");
304 if (!strncmp(stream_info->stream_type, STREAM_SOLO, SOUND_STREAM_TYPE_LEN) ||
305 !strncmp(stream_info->stream_type, STREAM_RADIO, SOUND_STREAM_TYPE_LEN) ||
306 !strncmp(stream_info->stream_type, STREAM_LOOPBACK_MIRRORING, SOUND_STREAM_TYPE_LEN)) {
307 stream_info->is_focus_unavailable = true;
308 LOGI("this stream_type[%s] does not support focus", stream_info->stream_type);
315 int _convert_stream_type_to_change_reason(const char *stream_type, sound_stream_focus_change_reason_e *change_reason)
317 SM_ARG_CHECK(stream_type);
318 SM_ARG_CHECK(change_reason);
320 if (!strncmp(stream_type, STREAM_MEDIA, SOUND_STREAM_TYPE_LEN) ||
321 !strncmp(stream_type, STREAM_COMPRESSED_MEDIA, SOUND_STREAM_TYPE_LEN) ||
322 !strncmp(stream_type, STREAM_RADIO, SOUND_STREAM_TYPE_LEN) ||
323 !strncmp(stream_type, STREAM_LOOPBACK, SOUND_STREAM_TYPE_LEN)) {
324 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
326 } else if (!strncmp(stream_type, STREAM_SYSTEM, SOUND_STREAM_TYPE_LEN)) {
327 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM;//LCOV_EXCL_LINE
329 } else if (!strncmp(stream_type, STREAM_ALARM, SOUND_STREAM_TYPE_LEN)) {
330 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_ALARM;
332 } else if (!strncmp(stream_type, STREAM_NOTIFICATION, SOUND_STREAM_TYPE_LEN)) {
333 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION;
335 } else if (!strncmp(stream_type, STREAM_EMERGENCY, SOUND_STREAM_TYPE_LEN)) {
336 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY;//LCOV_EXCL_LINE
338 } else if (!strncmp(stream_type, STREAM_VOICE_INFORMATION, SOUND_STREAM_TYPE_LEN)) {
339 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION;//LCOV_EXCL_LINE
341 } else if (!strncmp(stream_type, STREAM_VOICE_RECOGNITION, SOUND_STREAM_TYPE_LEN) ||
342 !strncmp(stream_type, STREAM_VOICE_RECOGNITION_SERVICE, SOUND_STREAM_TYPE_LEN)) {
343 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION;
345 } else if (!strncmp(stream_type, STREAM_RINGTONE_VOIP, SOUND_STREAM_TYPE_LEN) ||
346 !strncmp(stream_type, STREAM_RINGTONE_CALL, SOUND_STREAM_TYPE_LEN) ||
347 !strncmp(stream_type, STREAM_RINGBACKTONE_CALL, SOUND_STREAM_TYPE_LEN)) {
348 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE;
350 } else if (!strncmp(stream_type, STREAM_VOIP, SOUND_STREAM_TYPE_LEN)) {
351 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_VOIP;
353 } else if (!strncmp(stream_type, STREAM_CALL_VOICE, SOUND_STREAM_TYPE_LEN) ||
354 !strncmp(stream_type, STREAM_CALL_VIDEO, SOUND_STREAM_TYPE_LEN)) {
355 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_CALL;//LCOV_EXCL_LINE
357 } else if (!strncmp(stream_type, STREAM_EXT_MEDIA, SOUND_STREAM_TYPE_LEN)) {
358 *change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY;
362 LOGE("not supported stream_type(%s)", stream_type);
363 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
367 return SOUND_MANAGER_ERROR_NONE;
370 static int __get_dbus_connection(GDBusConnection **conn)
374 *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
375 if (!(*conn) || err) {
377 LOGE("g_bus_get_sync() error (%s)", err ? err->message : NULL);
380 return MM_ERROR_SOUND_INTERNAL;
384 return MM_ERROR_NONE;
387 int _convert_sound_type(sound_type_e sound_type, const char **volume_type)
389 SM_ARG_CHECK(volume_type);
391 switch (sound_type) {
392 case SOUND_TYPE_SYSTEM:
393 *volume_type = "system";
395 case SOUND_TYPE_NOTIFICATION:
396 *volume_type = "notification";
398 case SOUND_TYPE_ALARM:
399 *volume_type = "alarm";
401 case SOUND_TYPE_RINGTONE:
402 *volume_type = "ringtone";
404 case SOUND_TYPE_MEDIA:
405 *volume_type = "media";
407 case SOUND_TYPE_CALL:
408 *volume_type = "call";
410 case SOUND_TYPE_VOIP:
411 *volume_type = "voip";
413 case SOUND_TYPE_VOICE:
414 *volume_type = "voice";
417 LOGI("volume_type[%s]", *volume_type);
419 return SOUND_MANAGER_ERROR_NONE;
423 int _convert_sound_type_for_internal(sound_type_internal_e sound_type, const char **volume_type)
425 SM_ARG_CHECK(volume_type);
427 switch (sound_type) {
428 case SOUND_TYPE_BIXBY:
429 *volume_type = "bixby";
432 LOGI("volume_type[%s]", *volume_type);
434 return SOUND_MANAGER_ERROR_NONE;
438 int _convert_sound_type_to_enum(const char *sound_type, sound_type_e *sound_type_enum)
440 SM_ARG_CHECK(sound_type);
441 SM_ARG_CHECK(sound_type_enum);
443 if (!strncmp(sound_type, "system", strlen(sound_type))) {
444 *sound_type_enum = SOUND_TYPE_SYSTEM;//LCOV_EXCL_LINE
445 } else if (!strncmp(sound_type, "notification", strlen(sound_type))) {
446 *sound_type_enum = SOUND_TYPE_NOTIFICATION;//LCOV_EXCL_LINE
447 } else if (!strncmp(sound_type, "alarm", strlen(sound_type))) {
448 *sound_type_enum = SOUND_TYPE_ALARM;
449 } else if (!strncmp(sound_type, "ringtone", strlen(sound_type))) {
450 *sound_type_enum = SOUND_TYPE_RINGTONE;//LCOV_EXCL_LINE
451 } else if (!strncmp(sound_type, "media", strlen(sound_type))) {
452 *sound_type_enum = SOUND_TYPE_MEDIA;
453 } else if (!strncmp(sound_type, "call", strlen(sound_type))) {
454 *sound_type_enum = SOUND_TYPE_CALL;//LCOV_EXCL_LINE
455 } else if (!strncmp(sound_type, "voip", strlen(sound_type))) {
456 *sound_type_enum = SOUND_TYPE_VOIP;
457 } else if (!strncmp(sound_type, "voice", strlen(sound_type))) {
458 *sound_type_enum = SOUND_TYPE_VOICE;
461 SM_INTERNAL_SOUND_TYPE_CHECK(sound_type, SOUND_MANAGER_ERROR_NO_PLAYING_SOUND);
462 LOGE("not supported sound_type(%s)", sound_type);
463 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
467 return SOUND_MANAGER_ERROR_NONE;
470 int _convert_sound_type_to_enum_for_internal(const char *sound_type, sound_type_internal_e *sound_type_enum)
472 SM_ARG_CHECK(sound_type);
473 SM_ARG_CHECK(sound_type_enum);
475 if (!strncmp(sound_type, "bixby", strlen(sound_type))) {
476 *sound_type_enum = SOUND_TYPE_BIXBY;
478 SM_SOUND_TYPE_CHECK(sound_type, SOUND_MANAGER_ERROR_NO_PLAYING_SOUND);
479 LOGE("not supported internal sound_type(%s)", sound_type);
480 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
483 return SOUND_MANAGER_ERROR_NONE;
486 int _convert_device_type_enum_to_str(sound_device_type_e device_type, char **device_type_str)
488 SM_ARG_CHECK(device_type_str);
490 switch (device_type) {
491 case SOUND_DEVICE_BUILTIN_SPEAKER:
492 *device_type_str = "builtin-speaker";
494 case SOUND_DEVICE_BUILTIN_RECEIVER:
495 *device_type_str = "builtin-receiver";
497 case SOUND_DEVICE_BUILTIN_MIC:
498 *device_type_str = "builtin-mic";
500 case SOUND_DEVICE_AUDIO_JACK:
501 *device_type_str = "audio-jack";
503 case SOUND_DEVICE_BLUETOOTH_MEDIA:
504 *device_type_str = "bt-a2dp";
506 case SOUND_DEVICE_BLUETOOTH_VOICE:
507 *device_type_str = "bt-sco";
509 case SOUND_DEVICE_HDMI:
510 *device_type_str = "hdmi";
512 case SOUND_DEVICE_USB_AUDIO:
513 *device_type_str = "usb-audio";
515 case SOUND_DEVICE_FORWARDING:
516 *device_type_str = "forwarding";
518 case SOUND_DEVICE_NETWORK:
519 *device_type_str = "network";
522 LOGE("could not find the device_type[%d] in this switch case statement", device_type);
523 return SOUND_MANAGER_ERROR_INTERNAL;
526 LOGI("device_type[%s]", *device_type_str);
528 return SOUND_MANAGER_ERROR_NONE;
531 int _convert_device_type_str_to_enum(const char *device_type_str, sound_device_type_e *device_type)
533 SM_ARG_CHECK(device_type_str);
534 SM_ARG_CHECK(device_type);
536 if (!strncmp(device_type_str, "builtin-speaker", SOUND_DEVICE_TYPE_LEN)) {
537 *device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
539 } else if (!strncmp(device_type_str, "builtin-receiver", SOUND_DEVICE_TYPE_LEN)) {
540 *device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
542 } else if (!strncmp(device_type_str, "builtin-mic", SOUND_DEVICE_TYPE_LEN)) {
543 *device_type = SOUND_DEVICE_BUILTIN_MIC;
545 } else if (!strncmp(device_type_str, "audio-jack", SOUND_DEVICE_TYPE_LEN)) {
546 *device_type = SOUND_DEVICE_AUDIO_JACK;
547 } else if (!strncmp(device_type_str, "hdmi", SOUND_DEVICE_TYPE_LEN)) {
548 *device_type = SOUND_DEVICE_HDMI;
550 } else if (!strncmp(device_type_str, "usb-audio", SOUND_DEVICE_TYPE_LEN)) {
551 *device_type = SOUND_DEVICE_USB_AUDIO;
553 } else if (!strncmp(device_type_str, "bt-a2dp", SOUND_DEVICE_TYPE_LEN)) {
554 *device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
556 } else if (!strncmp(device_type_str, "bt-sco", SOUND_DEVICE_TYPE_LEN)) {
557 *device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
559 } else if (!strncmp(device_type_str, "network", SOUND_DEVICE_TYPE_LEN)) {
560 *device_type = SOUND_DEVICE_NETWORK;
563 LOGE("not supported device_type(%s)", device_type_str);
564 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
567 return SOUND_MANAGER_ERROR_NONE;
570 int _convert_device_type(mm_sound_device_type_e device_type, sound_device_type_e *sound_device_type)
572 SM_ARG_CHECK(sound_device_type);
574 switch (device_type) {
575 case MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER:
576 *sound_device_type = SOUND_DEVICE_BUILTIN_SPEAKER;
578 case MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER:
579 *sound_device_type = SOUND_DEVICE_BUILTIN_RECEIVER;
581 case MM_SOUND_DEVICE_TYPE_BUILTIN_MIC:
582 *sound_device_type = SOUND_DEVICE_BUILTIN_MIC;
585 case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
586 *sound_device_type = SOUND_DEVICE_AUDIO_JACK;
588 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP:
589 *sound_device_type = SOUND_DEVICE_BLUETOOTH_MEDIA;
591 case MM_SOUND_DEVICE_TYPE_BLUETOOTH_SCO:
592 *sound_device_type = SOUND_DEVICE_BLUETOOTH_VOICE;
594 case MM_SOUND_DEVICE_TYPE_HDMI:
595 *sound_device_type = SOUND_DEVICE_HDMI;
597 case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
598 *sound_device_type = SOUND_DEVICE_USB_AUDIO;
600 case MM_SOUND_DEVICE_TYPE_MIRRORING:
601 *sound_device_type = SOUND_DEVICE_FORWARDING;
603 case MM_SOUND_DEVICE_TYPE_NETWORK:
604 *sound_device_type = SOUND_DEVICE_NETWORK;
607 LOGE("not supported device_type(%d)", device_type);
608 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
612 return SOUND_MANAGER_ERROR_NONE;
615 int _convert_device_io_direction(mm_sound_device_io_direction_e io_direction, sound_device_io_direction_e *sound_io_direction)
617 SM_ARG_CHECK(sound_io_direction);
619 switch (io_direction) {
620 case MM_SOUND_DEVICE_IO_DIRECTION_IN:
621 *sound_io_direction = SOUND_DEVICE_IO_DIRECTION_IN;
623 case MM_SOUND_DEVICE_IO_DIRECTION_OUT:
624 *sound_io_direction = SOUND_DEVICE_IO_DIRECTION_OUT;
626 case MM_SOUND_DEVICE_IO_DIRECTION_BOTH:
627 *sound_io_direction = SOUND_DEVICE_IO_DIRECTION_BOTH;
631 return SOUND_MANAGER_ERROR_NONE;
634 const char* _convert_api_name(native_api_e api_name)
636 const char* name = NULL;
639 case NATIVE_API_SOUND_MANAGER:
640 name = "sound-manager";
642 case NATIVE_API_PLAYER:
645 case NATIVE_API_WAV_PLAYER:
648 case NATIVE_API_TONE_PLAYER:
649 name = "tone-player";
651 case NATIVE_API_AUDIO_IO:
654 case NATIVE_API_RECORDER:
662 int _convert_sample_format_enum_to_str(sound_sample_format_e format, char **format_str)
664 SM_ARG_CHECK(format_str);
667 case SOUND_SAMPLE_FORMAT_U8:
670 case SOUND_SAMPLE_FORMAT_S16_LE:
671 *format_str = "s16le";
673 case SOUND_SAMPLE_FORMAT_S24_LE:
674 *format_str = "s24le";
676 case SOUND_SAMPLE_FORMAT_S24_32_LE:
677 *format_str = "s24-32le";
680 LOGE("could not find format[%d] in this switch case statement", format);
681 return SOUND_MANAGER_ERROR_INTERNAL;
684 return SOUND_MANAGER_ERROR_NONE;
687 int _convert_sample_format_str_to_enum(const char *format_str, sound_sample_format_e *format)
689 SM_ARG_CHECK(format_str);
690 SM_ARG_CHECK(format);
692 if (!strncmp(format_str, "u8", SOUND_SAMPLE_FORMAT_LEN) || !strncmp(format_str, "8", SOUND_SAMPLE_FORMAT_LEN)) {
693 *format = SOUND_SAMPLE_FORMAT_U8;
694 } else if (!strncmp(format_str, "s16le", SOUND_SAMPLE_FORMAT_LEN)) {
695 *format = SOUND_SAMPLE_FORMAT_S16_LE;
696 } else if (!strncmp(format_str, "s24le", SOUND_SAMPLE_FORMAT_LEN)) {
697 *format = SOUND_SAMPLE_FORMAT_S24_LE;
698 } else if (!strncmp(format_str, "s24-32le", SOUND_SAMPLE_FORMAT_LEN)) {
699 *format = SOUND_SAMPLE_FORMAT_S24_32_LE;
701 LOGE("not supported sample format(%s)", format_str);
702 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
705 return SOUND_MANAGER_ERROR_NONE;
708 int _convert_sample_rate_enum_to_uint(sound_sample_rate_e rate, unsigned int *sample_rate)
710 SM_ARG_CHECK(sample_rate);
713 case SOUND_SAMPLE_RATE_8000:
716 case SOUND_SAMPLE_RATE_16000:
717 *sample_rate = 16000;
719 case SOUND_SAMPLE_RATE_22050:
720 *sample_rate = 22050;
722 case SOUND_SAMPLE_RATE_44100:
723 *sample_rate = 44100;
725 case SOUND_SAMPLE_RATE_48000:
726 *sample_rate = 48000;
728 case SOUND_SAMPLE_RATE_88200:
729 *sample_rate = 88200;
731 case SOUND_SAMPLE_RATE_96000:
732 *sample_rate = 96000;
734 case SOUND_SAMPLE_RATE_192000:
735 *sample_rate = 192000;
738 LOGE("not supported sample rate(%u)", rate);
739 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
742 return SOUND_MANAGER_ERROR_NONE;
745 int _convert_sample_rate_to_enum(unsigned int rate, sound_sample_rate_e *rate_e)
747 SM_ARG_CHECK(rate_e);
751 *rate_e = SOUND_SAMPLE_RATE_8000;
754 *rate_e = SOUND_SAMPLE_RATE_16000;
757 *rate_e = SOUND_SAMPLE_RATE_22050;
760 *rate_e = SOUND_SAMPLE_RATE_44100;
763 *rate_e = SOUND_SAMPLE_RATE_48000;
766 *rate_e = SOUND_SAMPLE_RATE_88200;
769 *rate_e = SOUND_SAMPLE_RATE_96000;
772 *rate_e = SOUND_SAMPLE_RATE_192000;
775 LOGE("not supported sample rate(%u)", rate);
776 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
779 return SOUND_MANAGER_ERROR_NONE;
783 int _return_val_if_not_usb_device(sound_device_h device, int ret_val)
785 mm_sound_device_type_e type;
787 if (mm_sound_get_device_type(device, &type))
790 if (type != MM_SOUND_DEVICE_TYPE_USB_AUDIO) {
791 LOGE("device type is not USB AUDIO");
795 return SOUND_MANAGER_ERROR_NONE;
799 void _focus_state_change_callback(int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason, int option, const char *extra_info, void *user_data)
801 int ret = MM_ERROR_NONE;
802 sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
803 sound_stream_info_s *stream_info;
808 LOGE("user_data is null");
812 stream_info = (sound_stream_info_s *)user_data;
813 if (stream_info->focus_id != index) {
814 LOGE("index is not valid, (%d, %d)", stream_info->focus_id, index);
818 if ((ret = _convert_stream_type_to_change_reason(reason, &change_reason))) {
819 LOGE("failed to _convert_stream_type_to_enum(), reason(%s), err(0x%08x)", reason, ret);
823 SM_ENTER_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
825 if (state == FOCUS_IS_RELEASED)
826 stream_info->acquired_focus &= ~focus_type;
827 else if (state == FOCUS_IS_ACQUIRED)
828 stream_info->acquired_focus |= focus_type;
830 if (state == FOCUS_IS_ACQUIRED)
831 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
833 LOGI("[FOCUS USER CALLBACK(%p) START]", stream_info->user_cb);
834 stream_info->user_cb((sound_stream_info_h)stream_info, focus_type, state, change_reason,
835 option, extra_info, stream_info->user_data);
836 LOGI("[FOCUS USER CALLBACK(%p) END]", stream_info->user_cb);
838 if (state == FOCUS_IS_RELEASED)
839 _update_focus_status(stream_info->pa_info.index, (unsigned int)stream_info->acquired_focus);
841 if (state == FOCUS_IS_RELEASED)
842 stream_info->prev_acquired_focus &= ~focus_type;
843 else if (state == FOCUS_IS_ACQUIRED)
844 stream_info->prev_acquired_focus |= focus_type;
846 SM_LEAVE_CRITICAL_SECTION(&stream_info->focus_cb_mutex);
854 void _focus_watch_callback(int index, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state, const char *reason, const char *extra_info, void *user_data)
856 int ret = MM_ERROR_NONE;
857 sound_stream_focus_change_reason_e change_reason = SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA;
858 _focus_watch_info_s *watch_info;
861 LOGE("user_data is null");
865 watch_info = (_focus_watch_info_s *)user_data;
866 if (watch_info->id != index) {
867 LOGE("index is not valid, (%d, %d)", watch_info->id, index);
871 if ((ret = _convert_stream_type_to_change_reason(reason, &change_reason))) {
872 LOGE("failed to _convert_stream_type_to_enum(), reason(%s), err(0x%08x)", reason, ret);
876 LOGI("[FOCUS WATCH USER CALLBACK(%p, id:%d) START]", watch_info->user_cb, index);
877 watch_info->user_cb(index, focus_type, state, change_reason, extra_info, watch_info->user_data);
878 LOGI("[FOCUS WATCH USER CALLBACK(%p) END]", watch_info->user_cb);
886 void _pa_context_state_cb(pa_context *c, void *userdata)
888 pa_context_state_t state;
889 sound_pa_info_s *pa_info = (sound_pa_info_s *)userdata;
893 state = pa_context_get_state(c);
895 LOGI("[%p] context state = [%d]", pa_info, state);
897 if (state == PA_CONTEXT_FAILED) {
898 pa_info->is_disconnected = true;
899 LOGE("PA DISCONNECTED");
903 case PA_CONTEXT_READY:
904 case PA_CONTEXT_TERMINATED:
905 case PA_CONTEXT_FAILED:
906 pa_threaded_mainloop_signal(pa_info->mainloop, 0);
908 case PA_CONTEXT_UNCONNECTED:
909 case PA_CONTEXT_CONNECTING:
910 case PA_CONTEXT_AUTHORIZING:
911 case PA_CONTEXT_SETTING_NAME:
919 void _pa_stream_state_cb(pa_stream *s, void * userdata)
921 pa_stream_state_t state;
922 virtual_sound_stream_info_s *vstream_h = (virtual_sound_stream_info_s*)userdata;
926 state = pa_stream_get_state(s);
927 LOGI("[%p] stream [%d] state = [%d]", vstream_h, pa_stream_get_index(s), state);
930 case PA_STREAM_READY:
931 case PA_STREAM_FAILED:
932 case PA_STREAM_TERMINATED:
933 pa_threaded_mainloop_signal(vstream_h->pa_mainloop, 0);
935 case PA_STREAM_UNCONNECTED:
936 case PA_STREAM_CREATING:
944 int _get_stream_conf_info(const char *stream_type, stream_conf_info_s *info)
946 int ret = SOUND_MANAGER_ERROR_NONE;
947 GVariant *result = NULL;
948 GVariant *child = NULL;
949 GDBusConnection *conn = NULL;
952 GVariant *item = NULL;
960 if ((ret = __get_dbus_connection(&conn)))
961 return SOUND_MANAGER_ERROR_INTERNAL;
963 result = g_dbus_connection_call_sync(conn,
965 PA_STREAM_MANAGER_OBJECT_PATH,
966 PA_STREAM_MANAGER_INTERFACE,
967 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO,
968 g_variant_new("(s)", stream_type),
969 G_VARIANT_TYPE("(vvvvvv)"),
970 G_DBUS_CALL_FLAGS_NONE,
974 if (!result || err) {
976 LOGE("g_dbus_connection_call_sync() for GET_STREAM_INFO error (%s)", err ? err->message : NULL);
979 ret = SOUND_MANAGER_ERROR_INTERNAL;
985 child = g_variant_get_child_value(result, 0);
986 item = g_variant_get_variant(child);
987 info->priority = g_variant_get_int32(item);
988 g_variant_unref(item);
989 g_variant_unref(child);
990 LOGI("priority(%d)", info->priority);
993 child = g_variant_get_child_value(result, 1);
994 item = g_variant_get_variant(child);
995 info->route_type = g_variant_get_int32(item);
996 g_variant_unref(item);
997 g_variant_unref(child);
998 LOGI("route_type(%d)", info->route_type);
1000 /* get volume types */
1001 child = g_variant_get_child_value(result, 2);
1002 item = g_variant_get_variant(child);
1003 g_variant_iter_init(&iter, item);
1004 while (g_variant_iter_loop(&iter, "&s", &name)) {
1005 if (name && !strncmp(name, "none", strlen("none")))
1007 /* we use volume type only for out direction */
1009 LOGI(" volume-type : %s", name);
1010 info->volume_type = strdup(name);
1014 g_variant_unref(item);
1015 g_variant_unref(child);
1017 /* get available in-devices */
1018 child = g_variant_get_child_value(result, 3);
1019 item = g_variant_get_variant(child);
1020 size = g_variant_n_children(item);
1021 LOGI("num of avail-in-devices are %"G_GSIZE_FORMAT, size);
1022 g_variant_iter_init(&iter, item);
1024 while (g_variant_iter_loop(&iter, "&s", &name)) {
1025 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1026 LOGI(" in-device is [%s], skip it", name);
1029 LOGI(" in-device name : %s", name);
1030 info->avail_in_devices[i++] = strdup(name);
1032 g_variant_unref(item);
1033 g_variant_unref(child);
1035 /* get available out-devices */
1036 child = g_variant_get_child_value(result, 4);
1037 item = g_variant_get_variant(child);
1038 size = g_variant_n_children(item);
1039 LOGI("num of avail-out-devices are %"G_GSIZE_FORMAT, size);
1040 g_variant_iter_init(&iter, item);
1042 while (g_variant_iter_loop(&iter, "&s", &name)) {
1043 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1044 LOGI(" out-device is [%s], skip it", name);
1047 LOGI(" out-device name : %s", name);
1048 info->avail_out_devices[i++] = strdup(name);
1050 g_variant_unref(item);
1051 g_variant_unref(child);
1053 /* get available frameworks */
1054 child = g_variant_get_child_value(result, 5);
1055 item = g_variant_get_variant(child);
1056 size = g_variant_n_children(item);
1057 LOGI("num of avail-frameworks are %"G_GSIZE_FORMAT, size);
1058 g_variant_iter_init(&iter, item);
1060 while (g_variant_iter_loop(&iter, "&s", &name)) {
1061 if (size == 1 && !strncmp(name, "none", strlen("none"))) {
1062 LOGI(" framework is [%s], skip it", name);//LCOV_EXCL_LINE
1065 LOGI(" framework name : %s", name);
1066 info->avail_frameworks[i++] = strdup(name);
1068 g_variant_unref(item);
1069 g_variant_unref(child);
1071 if (info->priority == -1) {
1072 LOGE("could not find the info of stream type(%s)", stream_type);//LCOV_EXCL_LINE
1073 ret = SOUND_MANAGER_ERROR_NOT_SUPPORTED;
1077 g_variant_unref(result);
1078 g_object_unref(conn);
1083 int _set_manual_route_info(unsigned int index, manual_route_info_s *info)
1085 int ret = SOUND_MANAGER_ERROR_NONE;
1087 GVariantBuilder *builder_for_in_devices;
1088 GVariantBuilder *builder_for_out_devices;
1089 GVariant *result = NULL;
1090 GDBusConnection *conn = NULL;
1092 const gchar *dbus_ret = NULL;
1096 if ((ret = __get_dbus_connection(&conn)))
1097 return SOUND_MANAGER_ERROR_INTERNAL;
1099 LOGI("stream info index(%u)", index);
1101 builder_for_in_devices = g_variant_builder_new(G_VARIANT_TYPE("au"));
1102 builder_for_out_devices = g_variant_builder_new(G_VARIANT_TYPE("au"));
1103 if (!builder_for_in_devices || !builder_for_out_devices) {
1104 LOGE("failed to g_variant_builder_new(), builder_for_in_devices(%p), builder_for_out_devices(%p)",
1105 builder_for_in_devices, builder_for_out_devices);
1106 ret = SOUND_MANAGER_ERROR_INTERNAL;
1109 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1110 if (!info->route_in_devices[i])
1112 g_variant_builder_add(builder_for_in_devices, "u", info->route_in_devices[i]);
1113 LOGI("[IN] device_id:%u", info->route_in_devices[i]);
1115 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
1116 if (!info->route_out_devices[i])
1118 g_variant_builder_add(builder_for_out_devices, "u", info->route_out_devices[i]);
1119 LOGI("[OUT] device_id:%u", info->route_out_devices[i]);
1122 result = g_dbus_connection_call_sync(conn,
1124 PA_STREAM_MANAGER_OBJECT_PATH,
1125 PA_STREAM_MANAGER_INTERFACE,
1126 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES,
1127 g_variant_new("(uauau)", index, builder_for_in_devices, builder_for_out_devices),
1128 G_VARIANT_TYPE("(s)"),
1129 G_DBUS_CALL_FLAGS_NONE,
1130 DBUS_METHOD_TIMEOUT,
1133 if (!result || err) {
1135 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_DEVICES error (%s)", err ? err->message : NULL);
1138 ret = SOUND_MANAGER_ERROR_INTERNAL;
1143 g_variant_get(result, "(&s)", &dbus_ret);
1144 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1145 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1146 ret = SOUND_MANAGER_ERROR_INTERNAL;
1148 info->is_set = true;
1151 g_variant_unref(result);
1152 if (builder_for_in_devices)
1153 g_variant_builder_unref(builder_for_in_devices);
1154 if (builder_for_out_devices)
1155 g_variant_builder_unref(builder_for_out_devices);
1156 g_object_unref(conn);
1162 int _set_route_option(unsigned int index, const char *name, int value)
1164 int ret = SOUND_MANAGER_ERROR_NONE;
1165 GVariant *result = NULL;
1166 GDBusConnection *conn = NULL;
1168 const gchar *dbus_ret = NULL;
1172 if ((ret = __get_dbus_connection(&conn)))
1173 return SOUND_MANAGER_ERROR_INTERNAL;
1175 LOGI("[OPTION] %s(%d)", name, value);
1177 result = g_dbus_connection_call_sync(conn,
1179 PA_STREAM_MANAGER_OBJECT_PATH,
1180 PA_STREAM_MANAGER_INTERFACE,
1181 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION,
1182 g_variant_new("(usi)", index, name, value),
1183 G_VARIANT_TYPE("(s)"),
1184 G_DBUS_CALL_FLAGS_NONE,
1185 DBUS_METHOD_TIMEOUT,
1188 if (!result || err) {
1189 LOGE("g_dbus_connection_call_sync() for SET_STREAM_ROUTE_OPTION error (%s)", err ? err->message : NULL);
1192 ret = SOUND_MANAGER_ERROR_INTERNAL;
1196 g_variant_get(result, "(&s)", &dbus_ret);
1197 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1198 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
1199 ret = SOUND_MANAGER_ERROR_INVALID_STATE;
1200 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1201 ret = SOUND_MANAGER_ERROR_INTERNAL;
1204 g_variant_unref(result);
1205 g_object_unref(conn);
1211 int _get_volume_max_level(const char *direction, const char *volume_type, unsigned int *max_level)
1213 int ret = SOUND_MANAGER_ERROR_NONE;
1214 GVariant *result = NULL;
1215 GDBusConnection *conn = NULL;
1217 const gchar *dbus_ret = NULL;
1220 assert(volume_type);
1223 if ((ret = __get_dbus_connection(&conn)))
1224 return SOUND_MANAGER_ERROR_INTERNAL;
1226 result = g_dbus_connection_call_sync(conn,
1228 PA_STREAM_MANAGER_OBJECT_PATH,
1229 PA_STREAM_MANAGER_INTERFACE,
1230 PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL,
1231 g_variant_new("(ss)", direction, volume_type),
1232 G_VARIANT_TYPE("(us)"),
1233 G_DBUS_CALL_FLAGS_NONE,
1234 DBUS_METHOD_TIMEOUT,
1237 if (!result || err) {
1239 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_MAX_LEVEL error (%s)", err ? err->message : NULL);
1242 ret = SOUND_MANAGER_ERROR_INTERNAL;
1247 g_variant_get(result, "(u&s)", max_level, &dbus_ret);
1248 LOGI("g_dbus_connection_call_sync() success, method return value is (%u, %s)", *max_level, dbus_ret);
1249 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1250 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1253 g_variant_unref(result);
1254 g_object_unref(conn);
1260 int _get_volume_level(const char *direction, const char *volume_type, unsigned int *level)
1262 int ret = SOUND_MANAGER_ERROR_NONE;
1263 GVariant *result = NULL;
1264 GDBusConnection *conn = NULL;
1266 const gchar *dbus_ret = NULL;
1269 assert(volume_type);
1272 if ((ret = __get_dbus_connection(&conn)))
1273 return SOUND_MANAGER_ERROR_INTERNAL;
1275 result = g_dbus_connection_call_sync(conn,
1277 PA_STREAM_MANAGER_OBJECT_PATH,
1278 PA_STREAM_MANAGER_INTERFACE,
1279 PA_STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL,
1280 g_variant_new("(ss)", direction, volume_type),
1281 G_VARIANT_TYPE("(us)"),
1282 G_DBUS_CALL_FLAGS_NONE,
1283 DBUS_METHOD_TIMEOUT,
1286 if (!result || err) {
1287 LOGE("g_dbus_connection_call_sync() for GET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1290 ret = SOUND_MANAGER_ERROR_INTERNAL;
1294 g_variant_get(result, "(u&s)", level, &dbus_ret);
1295 LOGI("g_dbus_connection_call_sync() success, method return value is (%u, %s)", *level, dbus_ret);
1296 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1297 ret = SOUND_MANAGER_ERROR_INTERNAL;
1300 g_variant_unref(result);
1301 g_object_unref(conn);
1306 int _set_volume_level(const char *direction, const char *volume_type, unsigned int level)
1308 int ret = SOUND_MANAGER_ERROR_NONE;
1309 GVariant *result = NULL;
1310 GDBusConnection *conn = NULL;
1312 const gchar *dbus_ret = NULL;
1314 char volume_path[VCONF_PATH_MAX] = {0,};
1317 assert(volume_type);
1319 if ((ret = __get_dbus_connection(&conn)))
1322 result = g_dbus_connection_call_sync(conn,
1324 PA_STREAM_MANAGER_OBJECT_PATH,
1325 PA_STREAM_MANAGER_INTERFACE,
1326 PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL,
1327 g_variant_new("(ssu)", direction, volume_type, level),
1328 G_VARIANT_TYPE("(s)"),
1329 G_DBUS_CALL_FLAGS_NONE,
1330 DBUS_METHOD_TIMEOUT,
1333 if (!result || err) {
1334 LOGE("g_dbus_connection_call_sync() for SET_VOLUME_LEVEL error (%s)", err ? err->message : NULL);
1337 ret = SOUND_MANAGER_ERROR_INTERNAL;
1341 g_variant_get(result, "(&s)", &dbus_ret);
1342 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1343 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1344 ret = SOUND_MANAGER_ERROR_INTERNAL;
1346 /* Set volume value to VCONF */
1347 snprintf(volume_path, sizeof(volume_path)-1, "%s%s", VCONF_PATH_PREFIX_VOLUME, volume_type);
1348 if ((vret = vconf_set_int(volume_path, (int)level)))
1349 LOGE("vconf_set_int(%s) failed..ret[%d]\n", volume_path, vret);
1353 g_variant_unref(result);
1354 g_object_unref(conn);
1360 int _get_current_volume_type(const char *direction, char **volume_type)
1362 int ret = SOUND_MANAGER_ERROR_NONE;
1363 GVariant *result = NULL;
1364 GDBusConnection *conn = NULL;
1366 const gchar *dbus_volume_type = NULL;
1367 const gchar *dbus_ret = NULL;
1370 assert(volume_type);
1372 if ((ret = __get_dbus_connection(&conn)))
1373 return SOUND_MANAGER_ERROR_INTERNAL;
1375 result = g_dbus_connection_call_sync(conn,
1377 PA_STREAM_MANAGER_OBJECT_PATH,
1378 PA_STREAM_MANAGER_INTERFACE,
1379 PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE,
1380 g_variant_new("(s)", direction),
1381 G_VARIANT_TYPE("(ss)"),
1382 G_DBUS_CALL_FLAGS_NONE,
1383 DBUS_METHOD_TIMEOUT,
1386 if (!result || err) {
1388 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_VOLUME_TYPE error (%s)", err ? err->message : NULL);
1391 ret = SOUND_MANAGER_ERROR_INTERNAL;
1396 g_variant_get(result, "(&s&s)", &dbus_volume_type, &dbus_ret);
1397 LOGI("g_dbus_connection_call_sync() success, method return value is (%s, %s)", dbus_volume_type, dbus_ret);
1398 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
1399 ret = SOUND_MANAGER_ERROR_NONE;//LCOV_EXCL_LINE
1400 *volume_type = strdup(dbus_volume_type);//LCOV_EXCL_LINE
1401 } else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret))) {
1402 ret = SOUND_MANAGER_ERROR_NO_PLAYING_SOUND;
1404 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1408 g_variant_unref(result);
1409 g_object_unref(conn);
1414 int _get_current_media_routing_path(const char *direction, sound_device_type_e *device_type)
1416 int ret = SOUND_MANAGER_ERROR_NONE;
1417 GVariant *result = NULL;
1418 GDBusConnection *conn = NULL;
1420 const gchar *dbus_device_type = NULL;
1421 const gchar *dbus_ret = NULL;
1424 assert(device_type);
1426 if ((ret = __get_dbus_connection(&conn)))
1427 return SOUND_MANAGER_ERROR_INTERNAL;
1429 result = g_dbus_connection_call_sync(conn,
1431 PA_STREAM_MANAGER_OBJECT_PATH,
1432 PA_STREAM_MANAGER_INTERFACE,
1433 PA_STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH,
1434 g_variant_new("(s)", direction),
1435 G_VARIANT_TYPE("(ss)"),
1436 G_DBUS_CALL_FLAGS_NONE,
1437 DBUS_METHOD_TIMEOUT,
1440 if (!result || err) {
1442 LOGE("g_dbus_connection_call_sync() for GET_CURRENT_MEDIA_ROUTING_PATH error (%s)", err ? err->message : NULL);
1445 ret = SOUND_MANAGER_ERROR_INTERNAL;
1450 g_variant_get(result, "(&s&s)", &dbus_device_type, &dbus_ret);
1451 LOGI("g_dbus_connection_call_sync() success, method return value is (%s, %s)", dbus_device_type, dbus_ret);
1452 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
1453 if (_convert_device_type_str_to_enum(dbus_device_type, device_type) < 0)
1454 ret = SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
1456 if (!strncmp("none", dbus_device_type, strlen(dbus_device_type)))
1457 ret = SOUND_MANAGER_ERROR_NO_DATA;
1459 ret = SOUND_MANAGER_ERROR_INTERNAL;
1463 g_variant_unref(result);
1464 g_object_unref(conn);
1469 void _update_focus_status(unsigned int index, unsigned int acquired_focus_status)
1471 GVariant *result = NULL;
1472 GDBusConnection *conn = NULL;
1474 const gchar *dbus_ret = NULL;
1476 if (__get_dbus_connection(&conn))
1479 result = g_dbus_connection_call_sync(conn,
1481 PA_STREAM_MANAGER_OBJECT_PATH,
1482 PA_STREAM_MANAGER_INTERFACE,
1483 PA_STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS,
1484 g_variant_new("(uu)", index, acquired_focus_status),
1485 G_VARIANT_TYPE("(s)"),
1486 G_DBUS_CALL_FLAGS_NONE,
1487 DBUS_METHOD_TIMEOUT,
1490 if (!result || err) {
1492 LOGE("g_dbus_connection_call_sync() for UPDATE_FOCUS_STATUS error (%s)", err ? err->message : NULL);
1498 g_variant_get(result, "(&s)", &dbus_ret);
1499 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
1500 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
1501 LOGE("failed to UPDATE_FOCUS_STATUS error (%s)", dbus_ret);//LCOV_EXCL_LINE
1504 g_variant_unref(result);
1505 g_object_unref(conn);
1511 int _is_device_running_by_id(int device_id, bool *is_running)
1513 int ret = SOUND_MANAGER_ERROR_NONE;
1514 GVariant *result = NULL;
1515 GDBusConnection *conn = NULL;
1517 gboolean _is_running;
1521 if ((ret = __get_dbus_connection(&conn)))
1522 return SOUND_MANAGER_ERROR_INTERNAL;
1524 result = g_dbus_connection_call_sync(conn,
1526 PA_DEVICE_MANAGER_OBJECT_PATH,
1527 PA_DEVICE_MANAGER_INTERFACE,
1528 PA_DEVICE_MANAGER_METHOD_NAME_IS_DEVICE_RUNNING_BY_ID,
1529 g_variant_new("(i)", device_id),
1530 G_VARIANT_TYPE("(b)"),
1531 G_DBUS_CALL_FLAGS_NONE,
1532 DBUS_METHOD_TIMEOUT,
1536 LOGE("g_dbus_connection_call_sync() for IS_DEVICE_RUNNING_BY_ID error (%s)", err->message);
1537 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1541 g_variant_get(result, "(b)", &_is_running);
1542 *is_running = (bool)_is_running;
1543 LOGI("device(id:%d) is (%s)", device_id, *is_running ? "Running" : "Not running");
1547 g_variant_unref(result);
1548 g_object_unref(conn);
1553 #define SM_SAMPLE_FORMAT_NUM 4 /* check declaration of sound_sample_format_e */
1554 int _get_supported_sample_formats(int device_id, sound_sample_format_e **formats, unsigned int *num)
1556 int ret = SOUND_MANAGER_ERROR_NONE;
1557 GVariant *result = NULL;
1558 GDBusConnection *conn = NULL;
1560 GVariantIter *iter = NULL;
1562 unsigned int iter_num;
1563 unsigned int elem_num = 0;
1564 sound_sample_format_e format;
1565 sound_sample_format_e sm_formats[SM_SAMPLE_FORMAT_NUM] = {0, };
1567 SM_ARG_CHECK(formats);
1570 if ((ret = __get_dbus_connection(&conn)))
1571 return SOUND_MANAGER_ERROR_INTERNAL;
1573 result = g_dbus_connection_call_sync(conn,
1575 PA_DEVICE_MANAGER_OBJECT_PATH,
1576 PA_DEVICE_MANAGER_INTERFACE,
1577 PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_FORMATS,
1578 g_variant_new("(i)", device_id),
1579 G_VARIANT_TYPE("(as)"),
1580 G_DBUS_CALL_FLAGS_NONE,
1581 DBUS_METHOD_TIMEOUT,
1584 if (!result || err) {
1585 LOGE("g_dbus_connection_call_sync() for GET_SUPPORTED_SAMPLE_FORMATS error (%s)", err ? err->message : NULL);
1586 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1592 g_variant_get(result, "(as)", &iter);
1593 if ((iter_num = (unsigned int) g_variant_iter_n_children(iter)) == 0) {
1594 LOGE("could not get supported sample formats");
1595 ret = SOUND_MANAGER_ERROR_INTERNAL;
1599 while (g_variant_iter_loop(iter, "&s", &format_str)) {
1600 if (_convert_sample_format_str_to_enum((const char *)format_str, &format))
1602 LOGI("%s(enum:%u) is supported", format_str, format);
1604 sm_formats[elem_num - 1] = format;
1607 if (elem_num == 0) {
1608 LOGE("could not find supported sample formats");
1609 ret = SOUND_MANAGER_ERROR_INTERNAL;
1613 if (!(*formats = (sound_sample_format_e *) calloc(elem_num, sizeof(sound_sample_format_e)))) {
1614 LOGE("failed to calloc(), elem_num(%d)", elem_num);
1615 ret = SOUND_MANAGER_ERROR_INTERNAL;
1618 memcpy(*formats, sm_formats, elem_num * sizeof(sound_sample_format_e));
1624 g_variant_iter_free(iter);
1625 g_variant_unref(result);
1626 g_object_unref(conn);
1631 int _set_sample_format(int device_id, sound_sample_format_e format)
1633 int ret = SOUND_MANAGER_ERROR_NONE;
1634 GDBusConnection *conn = NULL;
1636 char *format_str = NULL;
1638 if ((ret = __get_dbus_connection(&conn)))
1639 return SOUND_MANAGER_ERROR_INTERNAL;
1641 if ((ret = _convert_sample_format_enum_to_str(format, &format_str)))
1644 g_dbus_connection_call_sync(conn,
1646 PA_DEVICE_MANAGER_OBJECT_PATH,
1647 PA_DEVICE_MANAGER_INTERFACE,
1648 PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_FORMAT,
1649 g_variant_new("(is)", device_id, format_str),
1651 G_DBUS_CALL_FLAGS_NONE,
1652 DBUS_METHOD_TIMEOUT,
1656 LOGE("g_dbus_connection_call_sync() for SET_SAMPLE_FORMAT error (%s)", err->message);
1657 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1661 g_object_unref(conn);
1666 int _get_sample_format(int device_id, sound_sample_format_e *format)
1668 int ret = SOUND_MANAGER_ERROR_NONE;
1669 GVariant *result = NULL;
1670 GDBusConnection *conn = NULL;
1673 sound_sample_format_e format_e;
1675 SM_ARG_CHECK(format);
1677 if ((ret = __get_dbus_connection(&conn)))
1678 return SOUND_MANAGER_ERROR_INTERNAL;
1680 result = g_dbus_connection_call_sync(conn,
1682 PA_DEVICE_MANAGER_OBJECT_PATH,
1683 PA_DEVICE_MANAGER_INTERFACE,
1684 PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_FORMAT,
1685 g_variant_new("(i)", device_id),
1686 G_VARIANT_TYPE("(s)"),
1687 G_DBUS_CALL_FLAGS_NONE,
1688 DBUS_METHOD_TIMEOUT,
1691 if (!result || err) {
1692 LOGE("g_dbus_connection_call_sync() for GET_SAMPLE_FORMAT error (%s)", err ? err->message : NULL);
1693 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1698 g_variant_get(result, "(&s)", &format_str);
1699 if (!(ret = _convert_sample_format_str_to_enum((const char *)format_str, &format_e)))
1702 g_variant_unref(result);
1705 g_object_unref(conn);
1710 #define SM_SAMPLE_RATE_NUM 8 /* check declaration of sound_sample_rate_e */
1711 int _get_supported_sample_rates(int device_id, sound_sample_rate_e **rates, unsigned int *num)
1713 int ret = SOUND_MANAGER_ERROR_NONE;
1714 GVariant *result = NULL;
1715 GDBusConnection *conn = NULL;
1717 GVariantIter *iter = NULL;
1719 unsigned int iter_num;
1720 unsigned int elem_num = 0;
1721 sound_sample_rate_e rate_e;
1722 sound_sample_rate_e sm_rates[SM_SAMPLE_RATE_NUM] = {0, };
1724 SM_ARG_CHECK(rates);
1727 if ((ret = __get_dbus_connection(&conn)))
1728 return SOUND_MANAGER_ERROR_INTERNAL;
1730 result = g_dbus_connection_call_sync(conn,
1732 PA_DEVICE_MANAGER_OBJECT_PATH,
1733 PA_DEVICE_MANAGER_INTERFACE,
1734 PA_DEVICE_MANAGER_METHOD_NAME_GET_SUPPORTED_SAMPLE_RATES,
1735 g_variant_new("(i)", device_id),
1736 G_VARIANT_TYPE("(au)"),
1737 G_DBUS_CALL_FLAGS_NONE,
1738 DBUS_METHOD_TIMEOUT,
1741 if (!result || err) {
1742 LOGE("g_dbus_connection_call_sync() for GET_SUPPORTED_SAMPLE_RATES error (%s)", err ? err->message : NULL);
1743 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1749 g_variant_get(result, "(au)", &iter);
1750 if ((iter_num = (unsigned int) g_variant_iter_n_children(iter)) == 0) {
1751 LOGE("could not get supported sample rates");
1752 ret = SOUND_MANAGER_ERROR_INTERNAL;
1756 while (g_variant_iter_loop(iter, "u", &rate)) {
1757 if (_convert_sample_rate_to_enum(rate, &rate_e))
1759 LOGI("%u(enum:%u) is supported", rate, rate_e);
1761 sm_rates[elem_num - 1] = rate_e;
1764 if (elem_num == 0) {
1765 LOGE("could not find supported sample rates");
1766 ret = SOUND_MANAGER_ERROR_INTERNAL;
1770 if (!(*rates = (sound_sample_rate_e *) calloc(elem_num, sizeof(sound_sample_rate_e)))) {
1771 LOGE("failed to calloc(), elem_num(%d)", elem_num);
1772 ret = SOUND_MANAGER_ERROR_INTERNAL;
1775 memcpy(*rates, sm_rates, elem_num * sizeof(sound_sample_rate_e));
1781 g_variant_iter_free(iter);
1782 g_variant_unref(result);
1783 g_object_unref(conn);
1788 int _set_sample_rate(int device_id, sound_sample_rate_e rate)
1790 int ret = SOUND_MANAGER_ERROR_NONE;
1791 GDBusConnection *conn = NULL;
1795 if ((ret = __get_dbus_connection(&conn)))
1796 return SOUND_MANAGER_ERROR_INTERNAL;
1798 if ((ret = _convert_sample_rate_enum_to_uint(rate, &_rate)))
1801 g_dbus_connection_call_sync(conn,
1803 PA_DEVICE_MANAGER_OBJECT_PATH,
1804 PA_DEVICE_MANAGER_INTERFACE,
1805 PA_DEVICE_MANAGER_METHOD_NAME_SET_SAMPLE_RATE,
1806 g_variant_new("(iu)", device_id, _rate),
1808 G_DBUS_CALL_FLAGS_NONE,
1809 DBUS_METHOD_TIMEOUT,
1813 LOGE("g_dbus_connection_call_sync() for SET_SAMPLE_RATE error (%s)", err->message);
1814 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1818 g_object_unref(conn);
1823 int _get_sample_rate(int device_id, sound_sample_rate_e *rate)
1825 int ret = SOUND_MANAGER_ERROR_NONE;
1826 GVariant *result = NULL;
1827 GDBusConnection *conn = NULL;
1830 sound_sample_rate_e rate_e;
1832 SM_NULL_ARG_CHECK_FOR_PRIV(rate);
1834 if ((ret = __get_dbus_connection(&conn)))
1835 return SOUND_MANAGER_ERROR_INTERNAL;
1837 result = g_dbus_connection_call_sync(conn,
1839 PA_DEVICE_MANAGER_OBJECT_PATH,
1840 PA_DEVICE_MANAGER_INTERFACE,
1841 PA_DEVICE_MANAGER_METHOD_NAME_GET_SAMPLE_RATE,
1842 g_variant_new("(i)", device_id),
1843 G_VARIANT_TYPE("(u)"),
1844 G_DBUS_CALL_FLAGS_NONE,
1845 DBUS_METHOD_TIMEOUT,
1848 if (!result || err) {
1849 LOGE("g_dbus_connection_call_sync() for GET_SAMPLE_RATE error (%s)", err ? err->message : NULL);
1850 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1855 g_variant_get(result, "(u)", &_rate);
1856 if (!(ret = _convert_sample_rate_to_enum(_rate, &rate_e)))
1859 g_variant_unref(result);
1862 g_object_unref(conn);
1867 int _set_avoid_resampling(int device_id, bool enable)
1869 int ret = SOUND_MANAGER_ERROR_NONE;
1870 GDBusConnection *conn = NULL;
1873 if ((ret = __get_dbus_connection(&conn)))
1874 return SOUND_MANAGER_ERROR_INTERNAL;
1876 g_dbus_connection_call_sync(conn,
1878 PA_DEVICE_MANAGER_OBJECT_PATH,
1879 PA_DEVICE_MANAGER_INTERFACE,
1880 PA_DEVICE_MANAGER_METHOD_NAME_SET_AVOID_RESAMPLING,
1881 g_variant_new("(ib)", device_id, enable),
1883 G_DBUS_CALL_FLAGS_NONE,
1884 DBUS_METHOD_TIMEOUT,
1888 LOGE("g_dbus_connection_call_sync() for SET_AVOID_RESAMPLING error (%s)", err->message);
1889 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1893 g_object_unref(conn);
1898 int _get_avoid_resampling(int device_id, bool *enabled)
1900 int ret = SOUND_MANAGER_ERROR_NONE;
1901 GVariant *result = NULL;
1902 GDBusConnection *conn = NULL;
1906 SM_NULL_ARG_CHECK_FOR_PRIV(enabled);
1908 if ((ret = __get_dbus_connection(&conn)))
1909 return SOUND_MANAGER_ERROR_INTERNAL;
1911 result = g_dbus_connection_call_sync(conn,
1913 PA_DEVICE_MANAGER_OBJECT_PATH,
1914 PA_DEVICE_MANAGER_INTERFACE,
1915 PA_DEVICE_MANAGER_METHOD_NAME_GET_AVOID_RESAMPLING,
1916 g_variant_new("(i)", device_id),
1917 G_VARIANT_TYPE("(b)"),
1918 G_DBUS_CALL_FLAGS_NONE,
1919 DBUS_METHOD_TIMEOUT,
1922 if (!result || err) {
1923 LOGE("g_dbus_connection_call_sync() for GET_AVOID_RESAMPLING error (%s)", err ? err->message : NULL);
1924 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
1930 g_variant_get(result, "(b)", &_enabled);
1931 *enabled = (bool)_enabled;
1932 g_variant_unref(result);
1935 g_object_unref(conn);
1940 int _set_media_stream_only(int device_id, bool enable)
1942 int ret = SOUND_MANAGER_ERROR_NONE;
1943 GDBusConnection *conn = NULL;
1945 const char *stream_type;
1947 if ((ret = __get_dbus_connection(&conn)))
1948 return SOUND_MANAGER_ERROR_INTERNAL;
1951 stream_type = STREAM_MEDIA;
1953 stream_type = "none";
1955 g_dbus_connection_call_sync(conn,
1957 PA_DEVICE_MANAGER_OBJECT_PATH,
1958 PA_DEVICE_MANAGER_INTERFACE,
1959 PA_DEVICE_MANAGER_METHOD_NAME_SET_SPECIFIC_STREAM,
1960 g_variant_new("(is)", device_id, stream_type),
1962 G_DBUS_CALL_FLAGS_NONE,
1963 DBUS_METHOD_TIMEOUT,
1967 LOGE("g_dbus_connection_call_sync() for SET_SPECIFIC_STREAM error (%s)", err->message);
1968 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err->message));
1972 g_object_unref(conn);
1977 int _get_media_stream_only(int device_id, bool *enabled)
1979 int ret = SOUND_MANAGER_ERROR_NONE;
1980 GVariant *result = NULL;
1981 GDBusConnection *conn = NULL;
1985 SM_NULL_ARG_CHECK_FOR_PRIV(enabled);
1987 if ((ret = __get_dbus_connection(&conn)))
1988 return SOUND_MANAGER_ERROR_INTERNAL;
1990 result = g_dbus_connection_call_sync(conn,
1992 PA_DEVICE_MANAGER_OBJECT_PATH,
1993 PA_DEVICE_MANAGER_INTERFACE,
1994 PA_DEVICE_MANAGER_METHOD_NAME_GET_SPECIFIED_STREAM,
1995 g_variant_new("(i)", device_id),
1996 G_VARIANT_TYPE("(s)"),
1997 G_DBUS_CALL_FLAGS_NONE,
1998 DBUS_METHOD_TIMEOUT,
2001 if (!result || err) {
2002 LOGE("g_dbus_connection_call_sync() for GET_SPECIFIED_STREAM error (%s)", err ? err->message : NULL);
2003 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
2009 g_variant_get(result, "(&s)", &stream_type);
2010 if (!strncmp(stream_type, STREAM_MEDIA, SOUND_STREAM_TYPE_LEN))
2015 g_variant_unref(result);
2018 g_object_unref(conn);
2024 int _make_pa_connection(sound_pa_info_s *pa_info, const char *context_name)
2028 SM_ARG_CHECK(pa_info);
2030 if (!(pa_info->mainloop = pa_threaded_mainloop_new()))
2033 if (!(pa_info->context = pa_context_new(pa_threaded_mainloop_get_api(pa_info->mainloop), context_name)))
2036 pa_context_set_state_callback(pa_info->context, _pa_context_state_cb, pa_info);
2038 if (pa_context_connect(pa_info->context, NULL, 0, NULL) < 0) {
2039 pa_ret = pa_context_errno(pa_info->context);//LCOV_EXCL_LINE
2043 pa_threaded_mainloop_lock(pa_info->mainloop);
2045 if (pa_threaded_mainloop_start(pa_info->mainloop) < 0)
2046 goto PA_ERROR_WITH_UNLOCK;
2048 /* wait for ready state of the context */
2050 pa_context_state_t state;
2051 state = pa_context_get_state(pa_info->context);
2052 if (state == PA_CONTEXT_READY)
2054 if (!PA_CONTEXT_IS_GOOD(state)) {
2055 pa_ret = pa_context_errno(pa_info->context);//LCOV_EXCL_LINE
2056 goto PA_ERROR_WITH_UNLOCK;
2058 pa_threaded_mainloop_wait(pa_info->mainloop);
2061 /* get index of this context */
2062 pa_info->index = pa_context_get_index(pa_info->context);
2064 pa_threaded_mainloop_unlock(pa_info->mainloop);
2066 return SOUND_MANAGER_ERROR_NONE;
2068 PA_ERROR_WITH_UNLOCK:
2069 pa_threaded_mainloop_unlock(pa_info->mainloop);
2072 _destroy_pa_connection(pa_info);
2073 LOGE("pa_ret %d", pa_ret);
2075 return SOUND_MANAGER_ERROR_INTERNAL;
2079 int _make_pa_connection_and_register_focus(sound_stream_info_s *stream_h, sound_stream_focus_state_changed_cb callback, void *user_data)
2081 int ret = SOUND_MANAGER_ERROR_NONE;
2082 int mm_ret = MM_ERROR_NONE;
2084 bool is_focus_cb_thread = false;
2086 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
2087 return _convert_sound_manager_error_code(__func__, mm_ret);
2089 if (is_focus_cb_thread)
2090 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2092 /* get configuration information of this stream type */
2093 if ((ret = _get_stream_conf_info(stream_h->stream_type, &stream_h->stream_conf_info)))
2096 LOGI("stream_conf_info : stream type[%s], priority[%d], route type[%d]",
2097 stream_h->stream_type, stream_h->stream_conf_info.priority, stream_h->stream_conf_info.route_type);
2099 if ((ret = _make_pa_connection(&stream_h->pa_info, "SOUND_MANAGER_STREAM_INFO")))
2102 /* register focus */
2103 if (!stream_h->is_focus_unavailable) {
2104 mm_ret = mm_sound_register_focus(stream_h->stream_type, _focus_state_change_callback, stream_h, &stream_h->focus_id);
2105 if (mm_ret == MM_ERROR_NONE) {
2106 stream_h->user_cb = callback;
2107 stream_h->user_data = user_data;
2109 LOGE("failed to register focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2110 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2117 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2118 SM_SAFE_FREE(stream_h->stream_conf_info.avail_in_devices[i]);
2119 SM_SAFE_FREE(stream_h->stream_conf_info.avail_out_devices[i]);
2121 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2122 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2124 SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2126 _destroy_pa_connection(&stream_h->pa_info);
2132 void _destroy_pa_connection(sound_pa_info_s *pa_info)
2135 LOGW("NULL pa info - skip..");
2139 LOGI("[%p][%p]", pa_info->mainloop, pa_info->context);
2141 if (pa_info->mainloop)
2142 pa_threaded_mainloop_stop(pa_info->mainloop);
2144 if (pa_info->context) {
2145 pa_context_disconnect(pa_info->context);
2146 pa_context_unref(pa_info->context);
2147 pa_info->context = NULL;
2150 if (pa_info->mainloop) {
2151 pa_threaded_mainloop_free(pa_info->mainloop);
2152 pa_info->mainloop = NULL;
2158 int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h)
2161 int ret = SOUND_MANAGER_ERROR_NONE;
2162 int mm_ret = MM_ERROR_NONE;
2163 bool is_focus_cb_thread = false;
2165 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
2166 return _convert_sound_manager_error_code(__func__, mm_ret);
2168 if (is_focus_cb_thread)
2169 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
2171 _destroy_pa_connection(&stream_h->pa_info);
2173 /* unregister focus */
2174 if (!stream_h->is_focus_unavailable) {
2175 mm_ret = mm_sound_unregister_focus(stream_h->focus_id);
2177 LOGE("failed to unregister focus, ret(0x%x)", mm_ret);//LCOV_EXCL_LINE
2178 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2182 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2183 SM_SAFE_FREE(stream_h->stream_conf_info.avail_in_devices[i]);
2184 SM_SAFE_FREE(stream_h->stream_conf_info.avail_out_devices[i]);
2186 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++)
2187 SM_SAFE_FREE(stream_h->stream_conf_info.avail_frameworks[i]);
2189 SM_SAFE_FREE(stream_h->stream_conf_info.volume_type);
2194 static int __check_manual_route_type(sound_stream_info_s *stream_info)
2196 SM_ARG_CHECK(stream_info);
2198 if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL &&
2199 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL_EXT) {
2200 LOGE("route type is not manual or manual-ext");
2201 return SOUND_MANAGER_ERROR_POLICY;
2204 return SOUND_MANAGER_ERROR_NONE;
2207 static int __check_auto_route_type(sound_stream_info_s *stream_info)
2209 SM_ARG_CHECK(stream_info);
2211 if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO &&
2212 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
2213 LOGE("route type is not auto or auto-last-connected");
2214 return SOUND_MANAGER_ERROR_INTERNAL;
2217 return SOUND_MANAGER_ERROR_NONE;
2220 static int __add_device_to_stream_info(sound_stream_info_s *stream_info, int device_id, mm_sound_device_io_direction_e device_direction, char *device_type_str)
2223 bool added_successfully = false;
2225 SM_ARG_CHECK(stream_info);
2226 SM_ARG_CHECK(device_type_str);
2228 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2229 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2230 if (!stream_info->stream_conf_info.avail_in_devices[i])
2232 if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2235 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2236 if (!stream_info->manual_route_info.route_in_devices[j]) {
2237 stream_info->manual_route_info.route_in_devices[j] = (unsigned int)device_id;
2238 added_successfully = true;
2241 if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
2242 LOGE("failed to add device, this IN/BOTH-device[type:%s, id:%d] has been already set", device_type_str, device_id);
2243 return SOUND_MANAGER_ERROR_POLICY;
2248 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2249 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2250 if (!stream_info->stream_conf_info.avail_out_devices[i])
2252 if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2255 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2256 if (!stream_info->manual_route_info.route_out_devices[j]) {
2257 stream_info->manual_route_info.route_out_devices[j] = (unsigned int)device_id;
2258 added_successfully = true;
2261 if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
2262 LOGE("failed to add device, this OUT/BOTH-device[type:%s, id:%d] has been already set", device_type_str, device_id);
2263 return SOUND_MANAGER_ERROR_POLICY;
2269 if (!added_successfully) {
2270 LOGE("failed to add device, not supported device[type:%s, id:%d]", device_type_str, device_id);
2271 return SOUND_MANAGER_ERROR_POLICY;
2274 return SOUND_MANAGER_ERROR_NONE;
2277 static int __remove_device_from_stream_info(sound_stream_info_s *stream_info, int device_id, mm_sound_device_io_direction_e device_direction, char *device_type_str)
2280 bool removed_successfully = false;
2282 SM_ARG_CHECK(stream_info);
2283 SM_ARG_CHECK(device_type_str);
2285 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_IN || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2286 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2287 if (!stream_info->stream_conf_info.avail_in_devices[i])
2289 if (strncmp(stream_info->stream_conf_info.avail_in_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2292 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2293 if (stream_info->manual_route_info.route_in_devices[j] == (unsigned int)device_id) {
2294 removed_successfully = true;
2295 stream_info->manual_route_info.route_in_devices[j] = 0;
2301 if (device_direction == MM_SOUND_DEVICE_IO_DIRECTION_OUT || device_direction == MM_SOUND_DEVICE_IO_DIRECTION_BOTH) {
2302 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2303 if (!stream_info->stream_conf_info.avail_out_devices[i])
2305 if (strncmp(stream_info->stream_conf_info.avail_out_devices[i], device_type_str, SOUND_DEVICE_TYPE_LEN))
2308 for (j = 0; j < AVAIL_DEVICES_MAX; j++) {
2309 if (stream_info->manual_route_info.route_out_devices[j] == (unsigned int)device_id) {
2310 removed_successfully = true;
2311 stream_info->manual_route_info.route_out_devices[j] = 0;
2318 if (!removed_successfully) {
2319 LOGE("failed to remove device, could not find this device[type:%s, id:%d]", device_type_str, device_id);
2320 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
2323 return SOUND_MANAGER_ERROR_NONE;
2326 static int __is_available_device(sound_stream_info_s *stream_info, sound_device_h device, bool *available)
2328 int ret = SOUND_MANAGER_ERROR_NONE;
2329 int mm_ret = MM_ERROR_NONE;
2331 mm_sound_device_type_e mm_sound_device_type;
2332 sound_device_type_e device_type;
2333 char *device_type_str = NULL;
2334 char *avail_device_item = NULL;
2335 mm_sound_device_io_direction_e device_direction;
2338 SM_ARG_CHECK(stream_info);
2339 SM_ARG_CHECK(device);
2341 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)))
2342 return _convert_sound_manager_error_code(__func__, mm_ret);
2343 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2345 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2347 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)))
2348 return _convert_sound_manager_error_code(__func__, mm_ret);
2350 if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_OUT) {
2351 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2352 if (!(avail_device_item = stream_info->stream_conf_info.avail_out_devices[i]))
2354 if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2358 LOGE("[OUT] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2364 if (device_direction & MM_SOUND_DEVICE_IO_DIRECTION_IN) {
2366 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2367 if (!(avail_device_item = stream_info->stream_conf_info.avail_in_devices[i]))
2369 if (!strncmp(avail_device_item, device_type_str, strlen(device_type_str)))
2373 LOGE("[IN] this device(%s) is not available for this stream_info(%s)", device_type_str, stream_info->stream_type);
2384 int _add_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2386 int ret = SOUND_MANAGER_ERROR_NONE;
2387 int mm_ret = MM_ERROR_NONE;
2388 char *device_type_str = NULL;
2390 mm_sound_device_type_e mm_sound_device_type;
2391 mm_sound_device_io_direction_e device_direction;
2392 sound_device_type_e device_type;
2394 SM_ARG_CHECK(stream_info);
2395 SM_ARG_CHECK(device);
2397 if ((ret = __check_manual_route_type(stream_info)))
2400 if ((mm_ret = mm_sound_get_device_id(device, &device_id)))
2401 return _convert_sound_manager_error_code(__func__, mm_ret);
2402 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)))
2403 return _convert_sound_manager_error_code(__func__, mm_ret);
2404 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2406 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2408 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)))
2409 return _convert_sound_manager_error_code(__func__, mm_ret);
2411 if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)))
2414 LOGI("*** added device[type:%s, id:%d]", device_type_str, device_id);
2419 int _remove_device_for_stream_routing(sound_stream_info_s *stream_info, sound_device_h device)
2421 int ret = SOUND_MANAGER_ERROR_NONE;
2422 int mm_ret = MM_ERROR_NONE;
2423 char *device_type_str = NULL;
2425 mm_sound_device_type_e mm_sound_device_type;
2426 mm_sound_device_io_direction_e device_direction;
2427 sound_device_type_e device_type;
2429 SM_ARG_CHECK(stream_info);
2430 SM_ARG_CHECK(device);
2432 if ((ret = __check_manual_route_type(stream_info)))
2435 if ((mm_ret = mm_sound_get_device_id(device, &device_id)))
2436 return _convert_sound_manager_error_code(__func__, mm_ret);
2437 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type)))
2438 return _convert_sound_manager_error_code(__func__, mm_ret);
2439 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2441 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2443 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction)))
2444 return _convert_sound_manager_error_code(__func__, mm_ret);
2446 if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)))
2449 LOGI("*** removed device[type:%s, id:%d]", device_type_str, device_id);
2454 int _remove_all_devices_for_stream_routing(sound_stream_info_s *stream_info)
2456 int ret = SOUND_MANAGER_ERROR_NONE;
2459 SM_ARG_CHECK(stream_info);
2461 if ((ret = __check_manual_route_type(stream_info)))
2464 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2465 stream_info->manual_route_info.route_in_devices[i] = 0;
2466 stream_info->manual_route_info.route_out_devices[i] = 0;
2469 stream_info->manual_route_info.is_set = false;
2471 LOGI("*** removed all devices");
2476 int _add_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
2478 int ret = SOUND_MANAGER_ERROR_NONE;
2479 int mm_ret = MM_ERROR_NONE;
2480 char *device_type_str = NULL;
2481 mm_sound_device_type_e mm_sound_device_type;
2482 mm_sound_device_io_direction_e device_direction;
2483 sound_device_type_e device_type;
2484 MMSoundDevice_t device = NULL;
2486 SM_ARG_CHECK(stream_info);
2488 if ((ret = __check_manual_route_type(stream_info)))
2491 if ((mm_ret = mm_sound_get_device_by_id(device_id, &device)))
2492 return _convert_sound_manager_error_code(__func__, mm_ret);
2493 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type))) {
2494 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2497 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2499 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2501 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction))) {
2502 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2506 if ((ret = __add_device_to_stream_info(stream_info, device_id, device_direction, device_type_str)))
2509 LOGI("*** added device by id[type:%s, id:%d]", device_type_str, device_id);
2513 mm_sound_free_device(device);
2517 int _remove_device_id_for_stream_routing(sound_stream_info_s *stream_info, int device_id)
2519 int ret = SOUND_MANAGER_ERROR_NONE;
2520 int mm_ret = MM_ERROR_NONE;
2521 char *device_type_str = NULL;
2522 mm_sound_device_type_e mm_sound_device_type;
2523 mm_sound_device_io_direction_e device_direction;
2524 sound_device_type_e device_type;
2525 MMSoundDevice_t device = NULL;
2527 SM_ARG_CHECK(stream_info);
2529 if ((ret = __check_manual_route_type(stream_info)))
2532 if ((mm_ret = mm_sound_get_device_by_id(device_id, &device)))
2533 return _convert_sound_manager_error_code(__func__, mm_ret);
2534 if ((mm_ret = mm_sound_get_device_type(device, &mm_sound_device_type))) {
2535 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2538 if ((ret = _convert_device_type(mm_sound_device_type, &device_type)))
2540 if ((ret = _convert_device_type_enum_to_str(device_type, &device_type_str)))
2542 if ((mm_ret = mm_sound_get_device_io_direction(device, &device_direction))) {
2543 ret = _convert_sound_manager_error_code(__func__, mm_ret);
2547 if ((ret = __remove_device_from_stream_info(stream_info, device_id, device_direction, device_type_str)))
2550 LOGI("*** removed device by id[type:%s, id:%d]", device_type_str, device_id);
2554 mm_sound_free_device(device);
2558 int _apply_stream_routing(sound_stream_info_s *stream_info)
2562 SM_ARG_CHECK(stream_info);
2564 if (stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL &&
2565 stream_info->stream_conf_info.route_type != STREAM_ROUTE_TYPE_MANUAL_EXT) {
2566 LOGE("route type is not manual or manual-ext");//LCOV_EXCL_LINE
2567 /* Differ from others, it uses SOUND_INTERNAL error.
2568 * ACR process is required prior to changing error value. */
2569 return SOUND_MANAGER_ERROR_INTERNAL;//LCOV_EXCL_LINE
2572 for (i = 0; i < AVAIL_DEVICES_MAX; i++) {
2573 if (stream_info->manual_route_info.route_in_devices[i] ||
2574 stream_info->manual_route_info.route_out_devices[i])
2575 return _set_manual_route_info(stream_info->pa_info.index, &stream_info->manual_route_info);
2578 return SOUND_MANAGER_ERROR_INVALID_STATE;
2582 int _create_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_stream_info_s **virtual_stream)
2584 int ret = MM_ERROR_NONE;
2585 bool result = false;
2586 const char *name = NULL;
2589 SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2590 SM_INSTANCE_CHECK_FOR_PRIV(stream_info);
2592 /* check if this stream_info is available for virtual stream */
2593 name = _convert_api_name(NATIVE_API_SOUND_MANAGER);
2594 for (i = 0; i < AVAIL_FRAMEWORKS_MAX; i++) {
2595 if (stream_info->stream_conf_info.avail_frameworks[i] && !strncmp(stream_info->stream_conf_info.avail_frameworks[i], name, strlen(name))) {
2600 LOGI("stream_type[%s], native api[%s], is_available[%d]", stream_info->stream_type, name, result);
2601 if (result == false) {
2602 ret = MM_ERROR_NOT_SUPPORT_API;
2606 (*virtual_stream) = malloc(sizeof(virtual_sound_stream_info_s));
2607 if (!(*virtual_stream)) {
2608 ret = MM_ERROR_OUT_OF_MEMORY;
2612 memset((*virtual_stream), 0, sizeof(virtual_sound_stream_info_s));
2613 (*virtual_stream)->stream_type = stream_info->stream_type;
2614 (*virtual_stream)->pa_mainloop = stream_info->pa_info.mainloop;
2615 (*virtual_stream)->pa_context = stream_info->pa_info.context;
2616 (*virtual_stream)->pa_proplist = pa_proplist_new();
2617 pa_proplist_sets((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_ROLE, (*virtual_stream)->stream_type);
2618 pa_proplist_setf((*virtual_stream)->pa_proplist, PA_PROP_MEDIA_PARENT_ID, "%u", stream_info->pa_info.index);
2619 (*virtual_stream)->state = _VSTREAM_STATE_READY;
2620 (*virtual_stream)->stream_info = stream_info;
2626 int _destroy_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2628 int ret = MM_ERROR_NONE;
2630 SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2631 SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_READY);
2633 virtual_stream->pa_mainloop = NULL;
2634 virtual_stream->pa_context = NULL;
2635 if (virtual_stream->pa_proplist)
2636 pa_proplist_free(virtual_stream->pa_proplist);
2638 SM_SAFE_FREE(virtual_stream);
2643 int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2645 int ret = MM_ERROR_NONE;
2648 int io_direction = 0;
2650 pa_channel_map maps;
2652 SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2653 SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_READY);
2655 /* fill up with default value */
2658 ss.format = PA_SAMPLE_S16LE;
2659 pa_channel_map_init_auto(&maps, ss.channels, PA_CHANNEL_MAP_ALSA);
2661 /* check direction of this stream */
2662 if (virtual_stream->stream_info->stream_conf_info.avail_in_devices[0] != NULL)
2663 io_direction |= SOUND_STREAM_DIRECTION_INPUT;
2664 if (virtual_stream->stream_info->stream_conf_info.avail_out_devices[0] != NULL)
2665 io_direction |= SOUND_STREAM_DIRECTION_OUTPUT;
2667 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
2669 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2670 if (io_direction & (i + 1)) {
2671 virtual_stream->pa_stream[i] = pa_stream_new_with_proplist(virtual_stream->pa_context, "VIRTUAL_STREAM", &ss, &maps, virtual_stream->pa_proplist);
2672 if (virtual_stream->pa_stream[i] == NULL) {
2673 LOGE("failed to pa_stream_new_with_proplist()");
2674 pa_ret = pa_context_errno(virtual_stream->pa_context);
2675 ret = MM_ERROR_SOUND_INTERNAL;
2676 goto ERROR_WITH_UNLOCK;
2678 pa_stream_set_state_callback(virtual_stream->pa_stream[i], _pa_stream_state_cb, virtual_stream);
2680 if ((i + 1) == SOUND_STREAM_DIRECTION_OUTPUT) {
2681 pa_ret = pa_stream_connect_playback(virtual_stream->pa_stream[i], NULL, NULL, 0, NULL, NULL);
2683 LOGE("failed to pa_stream_connect_playback()");
2684 pa_ret = pa_context_errno(virtual_stream->pa_context);
2685 ret = MM_ERROR_SOUND_INTERNAL;
2686 goto ERROR_WITH_UNLOCK;
2688 } else if ((i + 1) == SOUND_STREAM_DIRECTION_INPUT) {
2689 pa_ret = pa_stream_connect_record(virtual_stream->pa_stream[i], NULL, NULL, 0);
2691 LOGE("failed to pa_stream_connect_record()");
2692 pa_ret = pa_context_errno(virtual_stream->pa_context);
2693 ret = MM_ERROR_SOUND_INTERNAL;
2694 goto ERROR_WITH_UNLOCK;
2698 /* wait for ready state of the stream */
2700 pa_stream_state_t state;
2701 state = pa_stream_get_state(virtual_stream->pa_stream[i]);
2702 if (state == PA_STREAM_READY)
2704 if (!PA_STREAM_IS_GOOD(state)) {
2705 LOGE("stream(%d) is not good, state : %d", i, state);
2706 pa_ret = pa_context_errno(virtual_stream->pa_context);
2707 ret = MM_ERROR_SOUND_INTERNAL;
2708 goto ERROR_WITH_UNLOCK;
2711 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
2715 virtual_stream->state = _VSTREAM_STATE_RUNNING;
2717 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2722 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2724 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2725 if (virtual_stream->pa_stream[i]) {
2726 pa_stream_unref(virtual_stream->pa_stream[i]);
2727 virtual_stream->pa_stream[i] = NULL;
2730 LOGE("pa_ret(%d)", pa_ret);
2734 int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream)
2736 int ret = MM_ERROR_NONE;
2739 SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2740 SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_RUNNING);
2742 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
2744 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2745 if (virtual_stream->pa_stream[i]) {
2746 pa_stream_disconnect(virtual_stream->pa_stream[i]);
2748 /* wait for terminated state of the stream */
2750 pa_stream_state_t state;
2751 state = pa_stream_get_state(virtual_stream->pa_stream[i]);
2752 if (state == PA_STREAM_TERMINATED)
2754 pa_threaded_mainloop_wait(virtual_stream->pa_mainloop);
2757 pa_stream_unref(virtual_stream->pa_stream[i]);
2758 virtual_stream->pa_stream[i] = NULL;
2762 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2764 virtual_stream->state = _VSTREAM_STATE_READY;
2769 int _set_volume_ratio(uint32_t stream_index, sound_stream_direction_e direction, double ratio)
2771 int ret = MM_ERROR_NONE;
2772 GDBusConnection *conn = NULL;
2774 GVariant *result = NULL;
2775 const gchar *dbus_ret = NULL;
2777 if ((ret = __get_dbus_connection(&conn)))
2780 result = g_dbus_connection_call_sync(conn,
2782 PA_STREAM_MANAGER_OBJECT_PATH,
2783 PA_STREAM_MANAGER_INTERFACE,
2784 PA_STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATIO,
2785 g_variant_new("(sud)", (direction == SOUND_STREAM_DIRECTION_OUTPUT) ? "out" : "in", stream_index, ratio),
2786 G_VARIANT_TYPE("(s)"),
2787 G_DBUS_CALL_FLAGS_NONE,
2788 DBUS_METHOD_TIMEOUT,
2791 if (!result || err) {
2792 LOGE("g_dbus_connection_call_sync() for SET_VOLUME_RATIO error (%s)", err ? err->message : NULL);
2793 ret = _convert_dbus_error(err ? err->message : NULL);
2798 g_variant_get(result, "(&s)", &dbus_ret);
2799 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
2800 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret)))
2801 ret = MM_ERROR_INVALID_ARGUMENT;
2802 else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
2803 ret = MM_ERROR_SOUND_NO_DATA;
2804 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
2805 ret = MM_ERROR_SOUND_INTERNAL;
2808 g_variant_unref(result);
2809 g_object_unref(conn);
2814 int _set_virtual_stream_volume(virtual_sound_stream_info_s *virtual_stream, double ratio)
2816 int ret = MM_ERROR_NONE;
2820 SM_INSTANCE_CHECK_FOR_PRIV(virtual_stream);
2821 SM_STATE_CHECK_FOR_PRIV(virtual_stream, _VSTREAM_STATE_RUNNING);
2823 pa_threaded_mainloop_lock(virtual_stream->pa_mainloop);
2825 for (i = 0; i < SOUND_STREAM_DIRECTION_MAX; i++) {
2826 if (virtual_stream->pa_stream[i]) {
2827 index = pa_stream_get_index(virtual_stream->pa_stream[i]);
2828 if ((ret = _set_volume_ratio(index, i + 1, ratio))) {
2829 if (ret == MM_ERROR_SOUND_NO_DATA) {
2830 LOGE("something wrong, no match index of %u", index);
2831 ret = MM_ERROR_SOUND_INTERNAL;
2838 pa_threaded_mainloop_unlock(virtual_stream->pa_mainloop);
2843 int _set_acm_master_mode(bool on)
2845 int ret = MM_ERROR_NONE;
2846 GVariant *result = NULL;
2847 GDBusConnection *conn = NULL;
2850 if ((ret = __get_dbus_connection(&conn)))
2853 result = g_dbus_connection_call_sync(conn,
2855 PA_DEVICE_MANAGER_OBJECT_PATH,
2856 PA_DEVICE_MANAGER_INTERFACE,
2857 PA_DEVICE_MANAGER_METHOD_NAME_SET_ACM_MODE,
2858 g_variant_new("(u)", (unsigned int)on),
2860 G_DBUS_CALL_FLAGS_NONE,
2861 DBUS_METHOD_TIMEOUT,
2865 LOGE("g_dbus_connection_call_sync() for SET ACM MODE error (%s)", err->message);
2866 ret = _convert_dbus_error(err->message);
2870 LOGI("ACM master mode [%s]", on ? "ON" : "OFF");
2874 g_variant_unref(result);
2875 g_object_unref(conn);
2880 int _activate_ducking(uint32_t stream_index, bool enable, const char *target_stream, uint32_t duration, double ratio)
2882 int ret = MM_ERROR_NONE;
2883 GDBusConnection *conn = NULL;
2885 GVariant *result = NULL;
2886 const gchar *dbus_ret = NULL;
2888 if ((ret = __get_dbus_connection(&conn)))
2891 result = g_dbus_connection_call_sync(conn,
2893 PA_STREAM_MANAGER_OBJECT_PATH,
2894 PA_STREAM_MANAGER_INTERFACE,
2895 PA_STREAM_MANAGER_METHOD_NAME_ACTIVATE_DUCKING,
2896 g_variant_new("(ubsud)", stream_index, enable, target_stream, duration, ratio),
2897 G_VARIANT_TYPE("(s)"),
2898 G_DBUS_CALL_FLAGS_NONE,
2899 DBUS_METHOD_TIMEOUT,
2902 if (!result || err) {
2903 LOGE("g_dbus_connection_call_sync() for ACTIVATE_DUCKING error");
2904 ret = _convert_dbus_error(err ? err->message : NULL);
2910 g_variant_get(result, "(&s)", &dbus_ret);
2912 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
2914 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_INVALID_STATE", dbus_ret, strlen(dbus_ret)))
2915 ret = MM_ERROR_SOUND_INVALID_STATE;
2916 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
2917 ret = MM_ERROR_SOUND_INTERNAL;
2920 g_variant_unref(result);
2921 g_object_unref(conn);
2926 int _get_ducking_state(sound_pa_info_s *pa_info, bool *is_ducked)
2928 int ret = MM_ERROR_NONE;
2929 gboolean _is_ducked = FALSE;
2930 GDBusConnection *conn = NULL;
2932 GVariant *result = NULL;
2933 const gchar *dbus_ret = NULL;
2935 SM_NULL_ARG_CHECK_FOR_PRIV(pa_info);
2936 SM_NULL_ARG_CHECK_FOR_PRIV(is_ducked);
2938 if (pa_info->is_disconnected) {
2939 LOGE("server disconnected");
2940 return MM_ERROR_SOUND_SERVER_DISCONNECTED;
2943 if ((ret = __get_dbus_connection(&conn)))
2946 result = g_dbus_connection_call_sync(conn,
2948 PA_STREAM_MANAGER_OBJECT_PATH,
2949 PA_STREAM_MANAGER_INTERFACE,
2950 PA_STREAM_MANAGER_METHOD_NAME_GET_DUCKING_STATE,
2951 g_variant_new("(u)", pa_info->index),
2952 G_VARIANT_TYPE("(bs)"),
2953 G_DBUS_CALL_FLAGS_NONE,
2954 DBUS_METHOD_TIMEOUT,
2957 if (!result || err) {
2958 LOGE("g_dbus_connection_call_sync() for GET_DUCKING_STATE error");
2959 ret = _convert_dbus_error(err ? err->message : NULL);
2965 g_variant_get(result, "(b&s)", &_is_ducked, &dbus_ret);
2967 LOGI("dbus return value is (%s)", dbus_ret);
2969 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
2970 *is_ducked = (bool)_is_ducked;
2971 LOGI("is_ducked %u", *is_ducked);
2973 ret = MM_ERROR_SOUND_INTERNAL;
2976 if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
2977 ret = MM_ERROR_SOUND_INTERNAL;
2980 g_variant_unref(result);
2981 g_object_unref(conn);
2986 static int __invoke_ipc_set_preferred_device_id(sound_stream_info_s *stream_info, int device_id, sound_device_io_direction_e io_direction, sound_device_io_direction_e req_direction)
2988 int ret = SOUND_MANAGER_ERROR_NONE;
2989 GVariant *result = NULL;
2990 GDBusConnection *conn = NULL;
2992 const gchar *dbus_ret = NULL;
2993 const gchar *direction_str;
2996 SM_ARG_CHECK(stream_info);
2998 if ((ret = __get_dbus_connection(&conn)))
2999 return SOUND_MANAGER_ERROR_INTERNAL;
3001 for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
3003 if (!(io_direction & (i + 1)))
3006 if (!((req_direction + 1) & (i + 1)))
3009 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3011 result = g_dbus_connection_call_sync(conn,
3013 PA_STREAM_MANAGER_OBJECT_PATH,
3014 PA_STREAM_MANAGER_INTERFACE,
3015 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE,
3016 g_variant_new("(usu)", stream_info->pa_info.index, direction_str, (unsigned int)device_id),
3018 G_DBUS_CALL_FLAGS_NONE,
3019 DBUS_METHOD_TIMEOUT,
3022 if (!result || err) {
3023 LOGE("g_dbus_connection_call_sync() for SET PREFERRED DEVICE error (%s)", err ? err->message : NULL);
3024 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3028 g_variant_unref(result);
3032 LOGI("Preferred device(id:%d, direction:%s) is set to PA context(%u)", device_id, direction_str, stream_info->pa_info.index);
3034 g_variant_get(result, "(&s)", &dbus_ret);
3035 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
3036 if (!strncmp("STREAM_MANAGER_RETURN_ERROR_DEVICE_NOT_FOUND", dbus_ret, strlen(dbus_ret)))
3037 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3038 else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
3039 ret = SOUND_MANAGER_ERROR_POLICY;
3040 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3041 ret = SOUND_MANAGER_ERROR_INTERNAL;
3043 g_variant_unref(result);
3047 if (i == SOUND_DEVICE_IO_DIRECTION_IN)
3048 stream_info->preferred_device_info.in = device_id;
3050 stream_info->preferred_device_info.out = device_id;
3054 g_object_unref(conn);
3058 int _set_preferred_device(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, sound_device_h device)
3060 int ret = SOUND_MANAGER_ERROR_NONE;
3061 int mm_ret = MM_ERROR_NONE;
3062 bool available = false;
3064 mm_sound_device_io_direction_e io_direction = MM_SOUND_DEVICE_IO_DIRECTION_IN;
3066 SM_ARG_CHECK(stream_info);
3068 /* allow only auto route type */
3069 if ((ret = __check_auto_route_type(stream_info)))
3072 /* check if this device belongs to available devices of the stream info */
3073 /* In case device is null, it's for unsetting preferred device, device_id will be 0. */
3075 if ((ret = __is_available_device(stream_info, device, &available)))
3078 return SOUND_MANAGER_ERROR_POLICY;
3079 if ((mm_ret = mm_sound_get_device_id(device, &device_id)))
3080 return _convert_sound_manager_error_code(__func__, mm_ret);
3081 if ((mm_ret = mm_sound_get_device_io_direction(device, &io_direction)))
3082 return _convert_sound_manager_error_code(__func__, mm_ret);
3083 if (!(io_direction & (direction + 1)) || ((int)io_direction < (int)(direction + 1))) {
3084 LOGE("device direction(0x%x), request direction(0x%x)", io_direction, (direction + 1));
3085 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3089 return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3092 int _set_preferred_device_id(sound_stream_info_s *stream_info, sound_device_io_direction_e direction, int device_id)
3094 int ret = SOUND_MANAGER_ERROR_NONE;
3095 int mm_ret = MM_ERROR_NONE;
3096 bool available = false;
3097 mm_sound_device_io_direction_e io_direction = MM_SOUND_DEVICE_IO_DIRECTION_IN;
3099 SM_ARG_CHECK(stream_info);
3101 /* allow only auto route type */
3102 if ((ret = __check_auto_route_type(stream_info)))
3105 /* check if this device belongs to available devices of the stream info */
3106 /* In case device_id is 0, it's for unsetting preferred device. */
3108 MMSoundDevice_t device = NULL;
3110 if ((mm_ret = mm_sound_get_device_by_id(device_id, &device))) {
3111 LOGE("failed to mm_sound_get_device_by_id()");
3112 return _convert_sound_manager_error_code(__func__, mm_ret);
3114 if ((ret = __is_available_device(stream_info, (sound_device_h)device, &available)))
3117 ret = SOUND_MANAGER_ERROR_POLICY;
3120 if ((mm_ret = mm_sound_get_device_io_direction(device, &io_direction))) {
3121 ret = _convert_sound_manager_error_code(__func__, mm_ret);
3124 if (!(io_direction & (direction + 1)) || ((int)io_direction < (int)(direction + 1))) {
3125 LOGE("device direction(0x%x), request direction(0x%x)", io_direction, (direction + 1));
3126 ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER;
3129 mm_sound_free_device(device);
3134 return __invoke_ipc_set_preferred_device_id(stream_info, device_id, io_direction, direction);
3137 int _get_preferred_device(sound_stream_info_s *stream_info, int *in_device_id, int *out_device_id)
3139 int ret = SOUND_MANAGER_ERROR_NONE;
3140 GDBusConnection *conn = NULL;
3142 GVariant *result = NULL;
3143 const gchar *dbus_ret = NULL;
3144 unsigned int _in_device_id;
3145 unsigned int _out_device_id;
3147 SM_ARG_CHECK(stream_info);
3149 if ((ret = __get_dbus_connection(&conn)))
3150 return SOUND_MANAGER_ERROR_INTERNAL;
3152 result = g_dbus_connection_call_sync(conn,
3154 PA_STREAM_MANAGER_OBJECT_PATH,
3155 PA_STREAM_MANAGER_INTERFACE,
3156 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE,
3157 g_variant_new("(u)", stream_info->pa_info.index),
3158 G_VARIANT_TYPE("(uus)"),
3159 G_DBUS_CALL_FLAGS_NONE,
3160 DBUS_METHOD_TIMEOUT,
3163 if (!result || err) {
3164 LOGE("g_dbus_connection_call_sync() for GET_STREAM_PREFERRED_DEVICE error");
3165 ret = _convert_sound_manager_error_code(__func__, _convert_dbus_error(err ? err->message : NULL));
3171 g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3173 LOGI("dbus return value is (%s)", dbus_ret);
3175 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3177 if (stream_info->preferred_device_info.in != _in_device_id) {
3178 LOGE("mismatching id [prev: %d, curr: %d]", stream_info->preferred_device_info.in, _in_device_id);
3179 ret = SOUND_MANAGER_ERROR_INTERNAL;
3181 *in_device_id = _in_device_id;
3182 LOGI("preferred device id[in:%d]", *in_device_id);
3185 if (out_device_id) {
3186 if (stream_info->preferred_device_info.out != _out_device_id) {
3187 LOGE("mismatching id [prev: %d, curr: %d]", stream_info->preferred_device_info.out, _out_device_id);
3188 ret = SOUND_MANAGER_ERROR_INTERNAL;
3190 *out_device_id = _out_device_id;
3191 LOGI("preferred device id[out:%d]", *out_device_id);
3195 ret = SOUND_MANAGER_ERROR_INTERNAL;
3199 g_variant_unref(result);
3200 g_object_unref(conn);
3205 static int __invoke_ipc_set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e io_direction, int device_id)
3207 int ret = MM_ERROR_NONE;
3208 GVariant *result = NULL;
3209 GDBusConnection *conn = NULL;
3211 const gchar *dbus_ret = NULL;
3212 const gchar *direction_str;
3213 char *stream_type_str;
3216 if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != MM_ERROR_NONE)
3219 if ((ret = __get_dbus_connection(&conn)))
3222 for (i = SOUND_DEVICE_IO_DIRECTION_IN; i < SOUND_DEVICE_IO_DIRECTION_BOTH; i++) {
3223 if (io_direction != SOUND_DEVICE_IO_DIRECTION_BOTH && io_direction != i)
3225 direction_str = (i == SOUND_DEVICE_IO_DIRECTION_IN) ? "in" : "out";
3227 result = g_dbus_connection_call_sync(conn,
3229 PA_STREAM_MANAGER_OBJECT_PATH,
3230 PA_STREAM_MANAGER_INTERFACE,
3231 PA_STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREEMPTIVE_DEVICE,
3232 g_variant_new("(ssu)", stream_type_str, direction_str, (unsigned int)device_id),
3234 G_DBUS_CALL_FLAGS_NONE,
3235 DBUS_METHOD_TIMEOUT,
3238 if (!result || err) {
3239 LOGE("g_dbus_connection_call_sync() for SET_STREAM_PREEMPTIVE_DEVICE, direction(%s) error (%s)",
3240 direction_str, err ? err->message : NULL);
3241 ret = _convert_dbus_error(err ? err->message : NULL);
3245 g_variant_unref(result);
3249 LOGI("Preemptive device(id:%d, direction:%s) is set", device_id, direction_str);
3251 g_variant_get(result, "(&s)", &dbus_ret);
3252 LOGI("g_dbus_connection_call_sync() success, method return value is (%s)", dbus_ret);
3253 if (!strncmp("STREAM_MANAGER_RETURN_INVALID_ARGUMENT", dbus_ret, strlen(dbus_ret)))
3254 ret = MM_ERROR_INVALID_ARGUMENT;
3255 else if (!strncmp("STREAM_MANAGER_RETURN_POLICY", dbus_ret, strlen(dbus_ret)))
3256 ret = MM_ERROR_POLICY_INTERNAL;
3257 else if (strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3258 ret = MM_ERROR_SOUND_INTERNAL;
3260 g_variant_unref(result);
3266 g_object_unref(conn);
3270 static int __invoke_ipc_get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3272 int ret = MM_ERROR_NONE;
3273 GDBusConnection *conn = NULL;
3275 GVariant *result = NULL;
3276 const gchar *dbus_ret = NULL;
3277 unsigned int _in_device_id;
3278 unsigned int _out_device_id;
3279 char *stream_type_str;
3281 if ((ret = _convert_stream_type(stream_type, &stream_type_str)) != MM_ERROR_NONE)
3284 if ((ret = __get_dbus_connection(&conn)))
3287 result = g_dbus_connection_call_sync(conn,
3289 PA_STREAM_MANAGER_OBJECT_PATH,
3290 PA_STREAM_MANAGER_INTERFACE,
3291 PA_STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREEMPTIVE_DEVICE,
3292 g_variant_new("(s)", stream_type_str),
3293 G_VARIANT_TYPE("(uus)"),
3294 G_DBUS_CALL_FLAGS_NONE,
3295 DBUS_METHOD_TIMEOUT,
3298 if (!result || err) {
3299 LOGE("g_dbus_connection_call_sync() for GET_STREAM_PREEMPTIVE_DEVICE error");
3300 ret = _convert_dbus_error(err ? err->message : NULL);
3305 g_variant_get(result, "(uu&s)", &_in_device_id, &_out_device_id, &dbus_ret);
3307 LOGI("dbus return value is (%s)", dbus_ret);
3309 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret))) {
3311 *in_device_id = _in_device_id;
3312 LOGI("preemptive device id[in:%d]", *in_device_id);
3314 if (out_device_id) {
3315 *out_device_id = _out_device_id;
3316 LOGI("preemptive device id[out:%d]", *out_device_id);
3319 ret = MM_ERROR_SOUND_INTERNAL;
3323 g_variant_unref(result);
3324 g_object_unref(conn);
3329 int _set_preemptive_device(sound_stream_type_e stream_type, sound_device_io_direction_e direction, int device_id)
3331 return __invoke_ipc_set_preemptive_device(stream_type, direction, device_id);
3334 int _get_preemptive_device(sound_stream_type_e stream_type, int *in_device_id, int *out_device_id)
3336 return __invoke_ipc_get_preemptive_device(stream_type, in_device_id, out_device_id);
3339 int _get_latest_stream_pid(int stream_type, unsigned int *pid)
3341 int ret = MM_ERROR_NONE;
3342 GDBusConnection *conn = NULL;
3344 GVariant *result = NULL;
3345 GVariantBuilder *builder_for_stream_types;
3346 const gchar *dbus_ret = NULL;
3349 SM_NULL_ARG_CHECK_FOR_PRIV(pid);
3351 if ((ret = __get_dbus_connection(&conn)))
3354 builder_for_stream_types = g_variant_builder_new(G_VARIANT_TYPE("as"));
3355 if (!builder_for_stream_types) {
3356 LOGE("failed to g_variant_builder_new()");
3357 ret = MM_ERROR_SOUND_INTERNAL;
3361 if (stream_type & STREAM_TYPE_MEDIA)
3362 g_variant_builder_add(builder_for_stream_types, "s", STREAM_MEDIA);
3363 if (stream_type & STREAM_TYPE_SYSTEM)
3364 g_variant_builder_add(builder_for_stream_types, "s", STREAM_SYSTEM);
3365 if (stream_type & STREAM_TYPE_ALARM)
3366 g_variant_builder_add(builder_for_stream_types, "s", STREAM_ALARM);
3367 if (stream_type & STREAM_TYPE_NOTIFICATION)
3368 g_variant_builder_add(builder_for_stream_types, "s", STREAM_NOTIFICATION);
3369 if (stream_type & STREAM_TYPE_EMERGENCY)
3370 g_variant_builder_add(builder_for_stream_types, "s", STREAM_EMERGENCY);
3371 if (stream_type & STREAM_TYPE_VOICE_INFORMATION)
3372 g_variant_builder_add(builder_for_stream_types, "s", STREAM_VOICE_INFORMATION);
3374 result = g_dbus_connection_call_sync(conn,
3376 PA_STREAM_MANAGER_OBJECT_PATH,
3377 PA_STREAM_MANAGER_INTERFACE,
3378 PA_STREAM_MANAGER_METHOD_NAME_GET_LASTEST_STREAM_PID,
3379 g_variant_new("(sas)", "out", builder_for_stream_types),
3380 G_VARIANT_TYPE("(us)"),
3381 G_DBUS_CALL_FLAGS_NONE,
3382 DBUS_METHOD_TIMEOUT,
3385 if (!result || err) {
3386 LOGE("g_dbus_connection_call_sync() for GET_LASTEST_STREAM_PID error");
3387 ret = _convert_dbus_error(err ? err->message : NULL);
3393 g_variant_get(result, "(u&s)", &_pid, &dbus_ret);
3395 LOGI("dbus return value is (%s)", dbus_ret);
3397 if (!strncmp("STREAM_MANAGER_RETURN_OK", dbus_ret, strlen(dbus_ret)))
3399 else if (!strncmp("STREAM_MANAGER_RETURN_ERROR_NO_STREAM", dbus_ret, strlen(dbus_ret)))
3400 ret = MM_ERROR_SOUND_NO_DATA;
3402 ret = MM_ERROR_SOUND_INTERNAL;
3405 if (builder_for_stream_types)
3406 g_variant_builder_unref(builder_for_stream_types);
3407 g_variant_unref(result);
3408 g_object_unref(conn);