4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <sys/types.h>
36 #include <mm_message.h>
38 #include "include/mm_sound_private.h"
39 #include "include/mm_sound.h"
40 #include "include/mm_sound_utils.h"
41 #include "include/mm_sound_client.h"
42 #include "include/mm_sound_pa_client.h"
43 #include "include/mm_ipc.h"
44 #include "include/mm_sound_common.h"
47 #define VOLUME_MAX_MULTIMEDIA 16
48 #define VOLUME_MAX_BASIC 8
49 #define VOLUME_MAX_SINGLE 1
52 #define MASTER_VOLUME_MAX 100
53 #define MASTER_VOLUME_MIN 0
55 static pthread_mutex_t g_volume_mutex = PTHREAD_MUTEX_INITIALIZER;
59 static GList *g_subscribe_cb_list = NULL;
60 static pthread_mutex_t g_subscribe_cb_list_mutex = PTHREAD_MUTEX_INITIALIZER;
62 #define MM_SOUND_DBUS_BUS_NAME_PREPIX "org.tizen.MMSound"
63 #define MM_SOUND_DBUS_OBJECT_PATH "/org/tizen/MMSound"
64 #define MM_SOUND_DBUS_INTERFACE "org.tizen.mmsound"
66 GDBusConnection *g_dbus_conn_mmsound;
68 int g_dbus_signal_values[MM_SOUND_SIGNAL_MAX] = {0,};
70 const char* dbus_signal_name_str[] = {
71 "ReleaseInternalFocus",
74 typedef struct _subscribe_cb {
75 mm_sound_signal_name_t signal_type;
76 mm_sound_signal_callback callback;
82 static const char* _get_volume_str (volume_type_t type)
84 static const char *volume_type_str[VOLUME_TYPE_MAX] =
85 { "SYSTEM", "NOTIFICATION", "ALARM", "RINGTONE", "MEDIA", "CALL", "VOIP", "VOICE", "FIXED"};
87 return (type >= VOLUME_TYPE_SYSTEM && type < VOLUME_TYPE_MAX)? volume_type_str[type] : "Unknown";
90 static int _validate_volume(volume_type_t type, int value)
97 case VOLUME_TYPE_CALL:
98 case VOLUME_TYPE_VOIP:
99 if (value >= VOLUME_MAX_BASIC) {
103 case VOLUME_TYPE_SYSTEM:
104 case VOLUME_TYPE_MEDIA:
105 case VOLUME_TYPE_ALARM:
106 case VOLUME_TYPE_NOTIFICATION:
107 case VOLUME_TYPE_RINGTONE:
108 case VOLUME_TYPE_VOICE:
109 if (value >= VOLUME_MAX_MULTIMEDIA) {
121 int mm_sound_volume_remove_callback(volume_type_t type)
123 /* FIXME : Will be removed */
124 return MM_ERROR_NOT_SUPPORT_API;
128 int mm_sound_add_volume_changed_callback(mm_sound_volume_changed_cb func, void* user_data, unsigned int *subs_id)
130 int ret = MM_ERROR_NONE;
132 if (func == NULL || subs_id == NULL) {
133 debug_error("argument is not valid\n");
134 return MM_ERROR_INVALID_ARGUMENT;
137 ret = mm_sound_client_add_volume_changed_callback(func, user_data, subs_id);
139 debug_error("Can not add volume changed callback, ret = %x\n", ret);
146 int mm_sound_remove_volume_changed_callback(unsigned int subs_id)
148 int ret = MM_ERROR_NONE;
150 ret = mm_sound_client_remove_volume_changed_callback(subs_id);
152 debug_error("Can not remove volume changed callback, ret = %x\n", ret);
159 int mm_sound_volume_set_value(volume_type_t volume_type, const unsigned int volume_level)
161 int ret = MM_ERROR_NONE;
163 debug_msg("type = (%d)%s, value = %d", volume_type, _get_volume_str(volume_type), volume_level);
165 /* Check input param */
166 if (0 > _validate_volume(volume_type, (int)volume_level)) {
167 debug_error("invalid volume type %d, value %u\n", volume_type, volume_level);
168 return MM_ERROR_INVALID_ARGUMENT;
171 ret = mm_sound_util_volume_set_value_by_type(volume_type, volume_level);
172 if (ret == MM_ERROR_NONE) {
173 /* update shared memory value */
174 if(MM_ERROR_NONE != mm_sound_client_set_volume_by_type(volume_type, volume_level)) {
175 debug_error("Can not set volume to shared memory 0x%x\n", ret);
183 int mm_sound_volume_get_value(volume_type_t type, unsigned int *value)
185 int ret = MM_ERROR_NONE;
187 /* Check input param */
189 debug_error("invalid argument\n");
190 return MM_ERROR_INVALID_ARGUMENT;
192 if (type < 0 || type >= VOLUME_TYPE_MAX) {
193 debug_error("invalid volume type value %d\n", type);
194 return MM_ERROR_INVALID_ARGUMENT;
197 ret = mm_sound_util_volume_get_value_by_type(type, value);
199 debug_msg("returned %s = %d", _get_volume_str(type), *value);
204 int mm_sound_volume_primary_type_set(volume_type_t type)
206 int ret = MM_ERROR_NONE;
208 /* Check input param */
209 if(type < VOLUME_TYPE_UNKNOWN || type >= VOLUME_TYPE_MAX) {
210 debug_error("invalid argument\n");
211 return MM_ERROR_INVALID_ARGUMENT;
214 if (vconf_set_int(VCONFKEY_SOUND_PRIMARY_VOLUME_TYPE, type)) {
215 debug_error("could not set vconf for RIMARY_VOLUME_TYPE\n");
216 ret = MM_ERROR_SOUND_INTERNAL;
218 debug_msg("set primary volume type forcibly %d(%s)", type, _get_volume_str(type));
225 int mm_sound_volume_primary_type_get(volume_type_t *type)
227 int ret = MM_ERROR_NONE;
228 int voltype = VOLUME_TYPE_RINGTONE;
230 /* Check input param */
232 debug_error("invalid argument\n");
233 return MM_ERROR_INVALID_ARGUMENT;
236 /* check force set */
237 if (vconf_get_int(VCONFKEY_SOUND_PRIMARY_VOLUME_TYPE, &voltype)) {
238 debug_error("could not get vconf for PRIMARY_VOLUME_TYPE\n");
239 ret = MM_ERROR_SOUND_INTERNAL;
241 debug_msg("get primary volume type %d(%s)", voltype, _get_volume_str(voltype));
248 ///////////////////////////////////
249 //// MMSOUND PLAY APIs
250 ///////////////////////////////////
251 static inline void _mm_sound_fill_play_param(MMSoundPlayParam *param, const char *filename, int volume_config, mm_sound_stop_callback_func callback, void *data, int priority, int handle_route)
253 param->filename = filename;
254 param->volume = 0; //volume value dose not effect anymore
255 param->callback = callback;
258 param->volume_config = volume_config;
259 param->priority = priority;
260 param->handle_route = handle_route;
264 int mm_sound_play_loud_solo_sound(const char *filename, int volume_config, mm_sound_stop_callback_func callback, void *data, int *handle)
266 MMSoundPlayParam param = { 0, };
268 /* FIXME : this function will be deleted */
269 _mm_sound_fill_play_param(¶m, filename, volume_config, callback, data, HANDLE_PRIORITY_NORMAL, MM_SOUND_HANDLE_ROUTE_USING_CURRENT);
270 return mm_sound_play_sound_ex(¶m, handle);
274 int mm_sound_play_sound(const char *filename, int volume_config, mm_sound_stop_callback_func callback, void *data, int *handle)
276 MMSoundPlayParam param = { 0, };
278 _mm_sound_fill_play_param(¶m, filename, volume_config, callback, data, HANDLE_PRIORITY_NORMAL, MM_SOUND_HANDLE_ROUTE_USING_CURRENT);
279 return mm_sound_play_sound_ex(¶m, handle);
283 int mm_sound_play_sound_ex(MMSoundPlayParam *param, int *handle)
288 /* Check input param */
290 debug_error("param is null\n");
291 return MM_ERROR_INVALID_ARGUMENT;
294 volume_type = MM_SOUND_VOLUME_CONFIG_TYPE(param->volume_config);
296 if (param->filename == NULL) {
297 debug_error("filename is NULL\n");
298 return MM_ERROR_SOUND_FILE_NOT_FOUND;
300 if (volume_type < 0 || volume_type >= VOLUME_TYPE_MAX) {
301 debug_error("Volume type is invalid %d\n", volume_type);
302 return MM_ERROR_INVALID_ARGUMENT;
305 debug_warning ("play sound : priority=[%d], handle_route=[%d]\n", param->priority, param->handle_route);
308 err = mm_sound_client_play_sound(param, 0, &lhandle);
310 debug_error("Failed to play sound\n");
314 /* Set handle to return */
318 debug_critical("The sound hadle cannot be get [%d]\n", lhandle);
321 debug_warning ("success : handle=[%p]\n", handle);
323 return MM_ERROR_NONE;
327 int mm_sound_play_sound_with_stream_info(const char *filename, char *stream_type, int stream_id, mm_sound_stop_callback_func callback, void *data, int *handle)
329 MMSoundPlayParam param = { 0, };
332 param.filename = filename;
333 param.volume = 0; //volume value dose not effect anymore
334 param.callback = callback;
337 param.priority = HANDLE_PRIORITY_NORMAL;
338 param.handle_route = MM_SOUND_HANDLE_ROUTE_USING_CURRENT;
340 err = mm_sound_client_play_sound_with_stream_info(¶m, handle, stream_type, stream_id);
342 debug_error("Failed to play sound\n");
346 debug_warning ("success : handle=[%p]\n", handle);
348 return MM_ERROR_NONE;
354 int mm_sound_stop_sound(int handle)
358 debug_warning ("enter : handle=[%p]\n", handle);
360 err = mm_sound_client_stop_sound(handle);
362 debug_error("Fail to stop sound\n");
365 debug_warning ("success : handle=[%p]\n", handle);
367 return MM_ERROR_NONE;
370 ///////////////////////////////////
371 //// MMSOUND TONE APIs
372 ///////////////////////////////////
374 int mm_sound_play_tone_ex (MMSoundTone_t num, int volume_config, const double volume, const int duration, int *handle, bool enable_session)
377 int err = MM_ERROR_NONE;
378 int volume_type = MM_SOUND_VOLUME_CONFIG_TYPE(volume_config);
382 /* Check input param */
384 debug_error("number is invalid %d\n", duration);
385 return MM_ERROR_INVALID_ARGUMENT;
387 if (num < MM_SOUND_TONE_DTMF_0 || num >= MM_SOUND_TONE_NUM) {
388 debug_error("TONE Value is invalid %d\n", num);
389 return MM_ERROR_INVALID_ARGUMENT;
391 if (volume_type < 0 || volume_type >= VOLUME_TYPE_MAX) {
392 debug_error("Volume type is invalid %d\n", volume_type);
393 return MM_ERROR_INVALID_ARGUMENT;
395 if (volume < 0.0 || volume > 1.0) {
396 debug_error("Volume Value is invalid %d\n", volume);
397 return MM_ERROR_INVALID_ARGUMENT;
401 debug_msg("Call MMSoundClientPlayTone\n");
402 err = mm_sound_client_play_tone(num, volume_config, volume, duration, &lhandle, enable_session);
404 debug_error("Failed to play sound\n");
408 /* Set handle to return */
412 debug_critical("The sound handle cannot be get [%d]\n", lhandle);
415 return MM_ERROR_NONE;
419 int mm_sound_play_tone_with_stream_info(MMSoundTone_t tone, char *stream_type, int stream_id, const double volume, const int duration, int *handle)
422 int err = MM_ERROR_NONE;
424 err = mm_sound_client_play_tone_with_stream_info(tone, stream_type, stream_id, volume, duration, handle);
426 debug_error("Failed to play sound\n");
436 int mm_sound_play_tone (MMSoundTone_t num, int volume_config, const double volume, const int duration, int *handle)
438 return mm_sound_play_tone_ex (num, volume_config, volume, duration, handle, true);
441 ///////////////////////////////////
442 //// MMSOUND ROUTING APIs
443 ///////////////////////////////////
446 int mm_sound_test(int a, int b, int* getv)
448 int ret = MM_ERROR_NONE;
450 debug_log("mm_sound_test enter");
452 debug_error("argu null");
453 return MM_ERROR_INVALID_ARGUMENT;
455 ret = mm_sound_client_test(a, b, getv);
457 debug_error("Can not mm sound test, ret = %x\n", ret);
459 debug_log("mm_sound_test leave");
465 int mm_sound_add_test_callback(mm_sound_test_cb func, void *user_data, unsigned int *subs_id)
467 int ret = MM_ERROR_NONE;
469 debug_log("mm_sound_add_test_callback enter");
470 if (!func || !subs_id) {
471 debug_error("argument is not valid\n");
472 return MM_ERROR_INVALID_ARGUMENT;
475 ret = mm_sound_client_add_test_callback(func, user_data, subs_id);
477 debug_error("Can not add test callback, ret = %x\n", ret);
479 debug_log("mm_sound_add_test_callback leave");
485 int mm_sound_remove_test_callback(unsigned int subs_id)
487 int ret = MM_ERROR_NONE;
489 debug_log("mm_sound_remove_test_callback enter");
490 ret = mm_sound_client_remove_test_callback(subs_id);
492 debug_error("Can not remove test callback, ret = %x\n", ret);
494 debug_log("mm_sound_remove_test_callback leave");
499 static int _convert_signal_name_str_to_enum (const char *name_str, mm_sound_signal_name_t *name_enum) {
500 int ret = MM_ERROR_NONE;
502 if (!name_str || !name_enum)
503 return MM_ERROR_INVALID_ARGUMENT;
505 if (!strncmp(name_str, "ReleaseInternalFocus", strlen("ReleaseInternalFocus"))) {
506 *name_enum = MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS;
508 ret = MM_ERROR_INVALID_ARGUMENT;
509 LOGE("not supported signal name(%s), err(0x%08x)", name_str, ret);
514 #define MASK_FOR_PID 0x00FFFFFF
515 #define MASK_FOR_VALUE 0x000000FF
516 static void _dbus_signal_callback (const char *signal_name, int value, void *user_data)
518 int ret = MM_ERROR_NONE;
519 mm_sound_signal_name_t signal;
520 subscribe_cb_t *subscribe_cb = (subscribe_cb_t*)user_data;
527 ret = _convert_signal_name_str_to_enum(signal_name, &signal);
531 debug_msg ("signal_name[%s], value[%d], user_data[0x%x]\n", signal_name, value, user_data);
533 if (subscribe_cb->signal_type == MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS) {
534 /* trigger the signal callback when it comes from the same process,
535 * in case of daemon usage, it uses the client_pid of subscribe_cb */
536 if ((subscribe_cb->client_pid ? (subscribe_cb->client_pid & MASK_FOR_PID) : (getpid() & MASK_FOR_PID)) == ((value & (MASK_FOR_PID << 8)) >> 8)) {
537 subscribe_cb->callback(signal, (value & MASK_FOR_VALUE), subscribe_cb->user_data);
540 subscribe_cb->callback(signal, value, subscribe_cb->user_data);
548 static void signal_callback(GDBusConnection *conn,
549 const gchar *sender_name,
550 const gchar *object_path,
551 const gchar *interface_name,
552 const gchar *signal_name,
553 GVariant *parameters,
557 const GVariantType* value_type;
559 debug_msg ("sender : %s, object : %s, interface : %s, signal : %s",
560 sender_name, object_path, interface_name, signal_name);
561 if (g_variant_is_of_type(parameters, G_VARIANT_TYPE("(i)"))) {
562 g_variant_get(parameters, "(i)",&value);
563 debug_msg(" - value : %d\n", value);
564 _dbus_signal_callback(signal_name, value, user_data);
566 value_type = g_variant_get_type(parameters);
567 debug_warning("signal type is %s", value_type);
572 int mm_sound_subscribe_signal(mm_sound_signal_name_t signal, unsigned int *subscribe_id, mm_sound_signal_callback callback, void *user_data)
574 int ret = MM_ERROR_NONE;
577 subscribe_cb_t *subscribe_cb = NULL;
581 MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_subscribe_cb_list_mutex, MM_ERROR_SOUND_INTERNAL);
583 if (signal < 0 || signal >= MM_SOUND_SIGNAL_MAX || !subscribe_id) {
584 debug_error ("invalid argument, signal(%d), subscribe_id(0x%p)", signal, subscribe_id);
585 ret = MM_ERROR_INVALID_ARGUMENT;
589 subscribe_cb = malloc(sizeof(subscribe_cb_t));
591 ret = MM_ERROR_SOUND_INTERNAL;
594 memset(subscribe_cb, 0, sizeof(subscribe_cb_t));
596 g_dbus_conn_mmsound = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
597 if (!g_dbus_conn_mmsound && err) {
598 debug_error ("g_bus_get_sync() error (%s) ", err->message);
600 ret = MM_ERROR_SOUND_INTERNAL;
604 subscribe_cb->signal_type = signal;
605 subscribe_cb->callback = callback;
606 subscribe_cb->user_data = user_data;
608 *subscribe_id = g_dbus_connection_signal_subscribe(g_dbus_conn_mmsound,
609 NULL, MM_SOUND_DBUS_INTERFACE, dbus_signal_name_str[signal], MM_SOUND_DBUS_OBJECT_PATH, NULL, 0,
610 signal_callback, subscribe_cb, NULL);
611 if (*subscribe_id == 0) {
612 debug_error ("g_dbus_connection_signal_subscribe() error (%d)", *subscribe_id);
613 ret = MM_ERROR_SOUND_INTERNAL;
617 subscribe_cb->id = *subscribe_id;
619 g_subscribe_cb_list = g_list_append(g_subscribe_cb_list, subscribe_cb);
620 if (g_subscribe_cb_list) {
621 debug_log("new subscribe_cb(0x%x)[user_callback(0x%x), subscribe_id(%u)] is added\n", subscribe_cb, subscribe_cb->callback, subscribe_cb->id);
623 debug_error("g_list_append failed\n");
624 ret = MM_ERROR_SOUND_INTERNAL;
628 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
635 g_dbus_connection_signal_unsubscribe(g_dbus_conn_mmsound, *subscribe_id);
636 g_object_unref(g_dbus_conn_mmsound);
642 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
648 int mm_sound_subscribe_signal_for_daemon(mm_sound_signal_name_t signal, int client_pid, unsigned int *subscribe_id, mm_sound_signal_callback callback, void *user_data)
650 int ret = MM_ERROR_NONE;
653 subscribe_cb_t *subscribe_cb = NULL;
657 MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_subscribe_cb_list_mutex, MM_ERROR_SOUND_INTERNAL);
659 if (signal < 0 || signal >= MM_SOUND_SIGNAL_MAX || !client_pid || !subscribe_id) {
660 debug_error ("invalid argument, signal(%d), client_pid(%d), subscribe_id(0x%p)", signal, client_pid, subscribe_id);
661 ret = MM_ERROR_INVALID_ARGUMENT;
665 subscribe_cb = malloc(sizeof(subscribe_cb_t));
667 ret = MM_ERROR_SOUND_INTERNAL;
670 memset(subscribe_cb, 0, sizeof(subscribe_cb_t));
672 g_dbus_conn_mmsound = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
673 if (!g_dbus_conn_mmsound && err) {
674 debug_error ("g_bus_get_sync() error (%s) ", err->message);
676 ret = MM_ERROR_SOUND_INTERNAL;
680 subscribe_cb->signal_type = signal;
681 subscribe_cb->callback = callback;
682 subscribe_cb->user_data = user_data;
683 subscribe_cb->client_pid = client_pid;
685 *subscribe_id = g_dbus_connection_signal_subscribe(g_dbus_conn_mmsound,
686 NULL, MM_SOUND_DBUS_INTERFACE, dbus_signal_name_str[signal], MM_SOUND_DBUS_OBJECT_PATH, NULL, 0,
687 signal_callback, subscribe_cb, NULL);
688 if (*subscribe_id == 0) {
689 debug_error ("g_dbus_connection_signal_subscribe() error (%d)", *subscribe_id);
690 ret = MM_ERROR_SOUND_INTERNAL;
694 subscribe_cb->id = *subscribe_id;
696 g_subscribe_cb_list = g_list_append(g_subscribe_cb_list, subscribe_cb);
697 if (g_subscribe_cb_list) {
698 debug_log("new subscribe_cb(0x%x)[user_callback(0x%x), subscribe_id(%u)] is added\n", subscribe_cb, subscribe_cb->callback, subscribe_cb->id);
700 debug_error("g_list_append failed\n");
701 ret = MM_ERROR_SOUND_INTERNAL;
705 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
712 g_dbus_connection_signal_unsubscribe(g_dbus_conn_mmsound, *subscribe_id);
713 g_object_unref(g_dbus_conn_mmsound);
719 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
725 void mm_sound_unsubscribe_signal(unsigned int subscribe_id)
728 subscribe_cb_t *subscribe_cb = NULL;
732 MMSOUND_ENTER_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
734 if (g_dbus_conn_mmsound && subscribe_id) {
735 g_dbus_connection_signal_unsubscribe(g_dbus_conn_mmsound, subscribe_id);
736 g_object_unref(g_dbus_conn_mmsound);
737 for (list = g_subscribe_cb_list; list != NULL; list = list->next) {
738 subscribe_cb = (subscribe_cb_t *)list->data;
739 if (subscribe_cb && (subscribe_cb->id == subscribe_id)) {
740 g_subscribe_cb_list = g_list_remove(g_subscribe_cb_list, subscribe_cb);
741 debug_log("subscribe_cb(0x%x) is removed\n", subscribe_cb);
747 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
753 int mm_sound_send_signal(mm_sound_signal_name_t signal, int value)
755 int ret = MM_ERROR_NONE;
757 GDBusConnection *conn = NULL;
758 gboolean dbus_ret = TRUE;
762 MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_subscribe_cb_list_mutex, MM_ERROR_SOUND_INTERNAL);
764 if (signal < 0 || signal >= MM_SOUND_SIGNAL_MAX) {
765 debug_error ("invalid argument, signal(%d)", signal);
766 ret = MM_ERROR_INVALID_ARGUMENT;
770 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
772 debug_error ("g_bus_get_sync() error (%s)", err->message);
773 ret = MM_ERROR_SOUND_INTERNAL;
777 g_dbus_signal_values[signal] = value;
778 if (signal == MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS) {
779 /* trigger the signal callback when it comes from the same process */
780 value |= ((int)getpid() << 8);
782 dbus_ret = g_dbus_connection_emit_signal (conn,
783 NULL, MM_SOUND_DBUS_OBJECT_PATH, MM_SOUND_DBUS_INTERFACE, dbus_signal_name_str[signal],
784 g_variant_new ("(i)", value),
786 if (!dbus_ret && err) {
787 debug_error ("g_dbus_connection_emit_signal() error (%s)", err->message);
788 ret = MM_ERROR_SOUND_INTERNAL;
792 dbus_ret = g_dbus_connection_flush_sync(conn, NULL, &err);
793 if (!dbus_ret && err) {
794 debug_error ("g_dbus_connection_flush_sync() error (%s)", err->message);
795 ret = MM_ERROR_SOUND_INTERNAL;
799 g_object_unref(conn);
800 debug_msg ("sending signal[%s], value[%d] success", dbus_signal_name_str[signal], value);
802 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
812 g_object_unref(conn);
814 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
820 int mm_sound_get_signal_value(mm_sound_signal_name_t signal, int *value)
822 int ret = MM_ERROR_NONE;
826 MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_subscribe_cb_list_mutex, MM_ERROR_SOUND_INTERNAL);
828 *value = g_dbus_signal_values[signal];
830 MMSOUND_LEAVE_CRITICAL_SECTION(&g_subscribe_cb_list_mutex);
837 __attribute__ ((constructor))
838 static void _mm_sound_initialize(void)
840 mm_sound_client_initialize();
844 __attribute__ ((destructor))
845 static void _mm_sound_finalize(void)
847 mm_sound_client_finalize();