13 #include "include/mm_sound_client_dbus.h"
14 #include "include/mm_sound_device.h"
15 #include "include/mm_sound_msg.h"
16 #include "include/mm_sound_common.h"
19 #include <security-server.h>
20 #define COOKIE_SIZE 20
24 #define BUS_NAME_PULSEAUDIO "org.pulseaudio.Server"
25 #define OBJECT_PULSE_MODULE_POLICY "/org/pulseaudio/policy1"
26 #define INTERFACE_PULSE_MODULE_POLICY "org.PulseAudio.Ext.Policy1"
27 #define OBJECT_PULSE_MODULE_DEVICE_MANAGER "/org/pulseaudio/DeviceManager"
28 #define INTERFACE_PULSE_MODULE_DEVICE_MANAGER "org.pulseaudio.DeviceManager"
29 #define OBJECT_PULSE_MODULE_STREAM_MANAGER "/org/pulseaudio/StreamManager"
30 #define INTERFACE_PULSE_MODULE_STREAM_MANAGER "org.pulseaudio.StreamManager"
32 #define BUS_NAME_SOUND_SERVER "org.tizen.SoundServer"
33 #define OBJECT_SOUND_SERVER "/org/tizen/SoundServer1"
34 #define INTERFACE_SOUND_SERVER "org.tizen.SoundServer1"
36 #define BUS_NAME_FOCUS_SERVER "org.tizen.FocusServer"
37 #define OBJECT_FOCUS_SERVER "/org/tizen/FocusServer1"
38 #define INTERFACE_FOCUS_SERVER "org.tizen.FocusServer1"
40 #define INTERFACE_DBUS "org.freedesktop.DBus.Properties"
41 #define SIGNAL_PROP_CHANGED "PropertiesChanged"
42 #define METHOD_GET "Get"
43 #define METHOD_SET "Set"
44 #define DBUS_NAME_MAX 32
45 #define DBUS_SIGNATURE_MAX 32
46 #define ERR_MSG_MAX 100
48 #define CODEC_HANDLE_MAX 256
51 DBUS_TO_PULSE_MODULE_DEVICE_MANAGER,
52 DBUS_TO_PULSE_MODULE_STREAM_MANAGER,
53 DBUS_TO_PULSE_MODULE_POLICY,
57 struct user_callback {
64 guint g_dbus_prop_subs_ids[PULSEAUDIO_PROP_MAX];
66 const struct mm_sound_dbus_method_info g_methods[METHOD_CALL_MAX] = {
67 [METHOD_CALL_TEST] = {
68 .name = "MethodTest1",
70 [METHOD_CALL_PLAY_FILE_START] = {
71 .name = "PlayFileStart",
73 [METHOD_CALL_PLAY_FILE_START_WITH_STREAM_INFO] = {
74 .name = "PlayFileStartWithStreamInfo",
76 [METHOD_CALL_PLAY_FILE_STOP] = {
77 .name = "PlayFileStop",
79 [METHOD_CALL_PLAY_DTMF] = {
82 [METHOD_CALL_PLAY_DTMF_WITH_STREAM_INFO] = {
83 .name = "PlayDTMFWithStreamInfo",
85 [METHOD_CALL_CLEAR_FOCUS] = {
88 [METHOD_CALL_GET_BT_A2DP_STATUS] = {
89 .name = "GetBTA2DPStatus",
91 [METHOD_CALL_SET_PATH_FOR_ACTIVE_DEVICE] = {
92 .name = "SetPathForActiveDevice",
94 [METHOD_CALL_GET_AUDIO_PATH] = {
95 .name = "GetAudioPath",
97 [METHOD_CALL_SET_VOLUME_LEVEL] = {
98 .name = "SetVolumeLevel",
100 [METHOD_CALL_GET_CONNECTED_DEVICE_LIST] = {
101 .name = "GetConnectedDeviceList",
103 [METHOD_CALL_REGISTER_FOCUS] = {
104 .name = "RegisterFocus",
106 [METHOD_CALL_UNREGISTER_FOCUS] = {
107 .name = "UnregisterFocus",
109 [METHOD_CALL_ACQUIRE_FOCUS] = {
110 .name = "AcquireFocus",
112 [METHOD_CALL_RELEASE_FOCUS] = {
113 .name = "ReleaseFocus",
115 [METHOD_CALL_WATCH_FOCUS] = {
116 .name = "WatchFocus",
118 [METHOD_CALL_UNWATCH_FOCUS] = {
119 .name = "UnwatchFocus",
121 [METHOD_CALL_EMERGENT_EXIT_FOCUS] = {
122 .name = "EmergentExitFocus",
126 const struct mm_sound_dbus_signal_info g_signals[SIGNAL_MAX] = {
128 .name = "SignalTest1",
130 [SIGNAL_PLAY_FILE_END] = {
131 .name = "PlayFileEnd",
133 [SIGNAL_VOLUME_CHANGED] = {
134 .name = "VolumeChanged",
136 [SIGNAL_DEVICE_CONNECTED] = {
137 .name = "DeviceConnected",
139 [SIGNAL_DEVICE_INFO_CHANGED] = {
140 .name = "DeviceInfoChanged",
142 [SIGNAL_FOCUS_CHANGED] = {
143 .name = "FocusChanged",
145 [SIGNAL_FOCUS_WATCH] = {
146 .name = "FocusWatch",
150 const struct pulseaudio_dbus_property_info g_pulseaudio_properties[PULSEAUDIO_PROP_MAX] = {
151 [PULSEAUDIO_PROP_AUDIO_BALANCE] = {
152 .name = "AudioBalance",
154 [PULSEAUDIO_PROP_MONO_AUDIO] = {
157 [PULSEAUDIO_PROP_MUTE_ALL] = {
163 static const GDBusErrorEntry mm_sound_client_error_entries[] =
165 {MM_ERROR_SOUND_INTERNAL, "org.tizen.mm.sound.Error.Internal"},
166 {MM_ERROR_INVALID_ARGUMENT, "org.tizen.mm.sound.Error.InvalidArgument"},
171 /* Only For error types which is currently being used in server-side */
172 static const GDBusErrorEntry mm_sound_error_entries[] =
174 {MM_ERROR_OUT_OF_MEMORY, "org.tizen.multimedia.OutOfMemory"},
175 {MM_ERROR_OUT_OF_STORAGE, "org.tizen.multimedia.OutOfStorage"},
176 {MM_ERROR_INVALID_ARGUMENT, "org.tizen.multimedia.InvalidArgument"},
177 {MM_ERROR_POLICY_INTERNAL, "org.tizen.multimedia.PolicyInternal"},
178 {MM_ERROR_NOT_SUPPORT_API, "org.tizen.multimedia.NotSupportAPI"},
179 {MM_ERROR_POLICY_BLOCKED, "org.tizen.multimedia.PolicyBlocked"},
180 {MM_ERROR_END_OF_FILE, "org.tizen.multimedia.EndOfFile"},
181 {MM_ERROR_COMMON_OUT_OF_RANGE, "org.tizen.multimedia.common.OutOfRange"},
182 {MM_ERROR_COMMON_UNKNOWN, "org.tizen.multimedia.common.Unknown"},
183 {MM_ERROR_COMMON_NO_FREE_SPACE, "org.tizen.multimedia.common.NoFreeSpace"},
184 {MM_ERROR_SOUND_INTERNAL, "org.tizen.multimedia.audio.Internal"},
185 {MM_ERROR_SOUND_INVALID_STATE, "org.tizen.multimedia.audio.InvalidState"},
186 {MM_ERROR_SOUND_NO_FREE_SPACE, "org.tizen.multimedia.audio.NoFreeSpace"},
187 {MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE, "org.tizen.multimedia.audio.UnsupportedMediaType"},
188 {MM_ERROR_SOUND_INVALID_POINTER, "org.tizen.multimedia.audio.InvalidPointer"},
189 {MM_ERROR_SOUND_INVALID_FILE, "org.tizen.multimedia.audio.InvalidFile"},
190 {MM_ERROR_SOUND_FILE_NOT_FOUND, "org.tizen.multimedia.audio.FileNotFound"},
191 {MM_ERROR_SOUND_NO_DATA, "org.tizen.multimedia.audio.NoData"},
192 {MM_ERROR_SOUND_INVALID_PATH, "org.tizen.multimedia.audio.InvalidPath"},
196 /******************************************************************************************
197 Wrapper Functions of GDbus
198 ******************************************************************************************/
201 static int _parse_error_msg(char *full_err_msg, char **err_name, char **err_msg)
203 char *save_p, *domain, *_err_name, *_err_msg;
205 if (!(domain = strtok_r(full_err_msg, ":", &save_p))) {
206 debug_error("get domain failed");
209 if (!(_err_name = strtok_r(NULL, ":", &save_p))) {
210 debug_error("get err name failed");
213 if (!(_err_msg = strtok_r(NULL, ":", &save_p))) {
214 debug_error("get err msg failed");
218 *err_name = _err_name;
224 static int _convert_error_name(const char *err_name)
228 for (i = 0; i < G_N_ELEMENTS(mm_sound_error_entries); i++) {
229 if (!strcmp(mm_sound_error_entries[i].dbus_error_name, err_name)) {
230 return mm_sound_error_entries[i].error_code;
234 return MM_ERROR_COMMON_UNKNOWN;
237 static int _dbus_method_call(GDBusConnection* conn, const char* bus_name, const char* object, const char* intf,
238 const char* method, GVariant* args, GVariant** result)
240 int ret = MM_ERROR_NONE;
242 GVariant* dbus_reply = NULL;
244 if (!conn || !object || !intf || !method) {
245 debug_error("Invalid Argument");
247 debug_error("conn null");
249 debug_error("object null");
251 debug_error("intf null");
253 debug_error("method null");
254 return MM_ERROR_INVALID_ARGUMENT;
257 debug_log("Dbus call with obj'%s' intf'%s' method'%s'", object, intf, method);
259 dbus_reply = g_dbus_connection_call_sync(conn, bus_name, object , intf, \
261 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err );
262 if (dbus_reply && !err) {
263 debug_log("Method Call '%s.%s' Success", intf, method);
264 *result = dbus_reply;
266 char *err_name = NULL, *err_msg = NULL;
267 debug_log("Method Call '%s.%s' Failed, %s", intf, method, err->message);
269 if (_parse_error_msg(err->message, &err_name, &err_msg) < 0) {
270 debug_error("failed to parse error message");
272 return MM_ERROR_SOUND_INTERNAL;
274 ret = _convert_error_name(err_name);
281 static int _dbus_set_property(GDBusConnection* conn, const char* bus_name, const char* object, const char* intf,
282 const char* prop, GVariant* args, GVariant** result)
284 int ret = MM_ERROR_NONE;
286 if (!conn || !object || !intf || !prop) {
287 debug_error("Invalid Argument");
288 return MM_ERROR_INVALID_ARGUMENT;
291 debug_log("Dbus set property with obj'%s' intf'%s' prop'%s'", object, intf, prop);
293 if ((ret = _dbus_method_call(conn, bus_name, object, INTERFACE_DBUS, METHOD_SET,
294 g_variant_new("(ssv)", intf, prop, args), result)) != MM_ERROR_NONE) {
295 debug_error("Dbus call for set property failed");
301 static int _dbus_get_property(GDBusConnection *conn, const char* bus_name, const char* object_name,
302 const char* intf_name, const char* prop, GVariant** result)
304 int ret = MM_ERROR_NONE;
306 if (!conn || !object_name || !intf_name || !prop) {
307 debug_error("Invalid Argument");
308 return MM_ERROR_INVALID_ARGUMENT;
311 debug_log("Dbus get property with obj'%s' intf'%s' prop'%s'", object_name, intf_name, prop);
313 if ((ret = _dbus_method_call(conn,
314 bus_name, object_name, INTERFACE_DBUS, METHOD_GET,
315 g_variant_new("(ss)", intf_name, prop), result)) != MM_ERROR_NONE) {
316 debug_error("Dbus call for get property failed");
322 static int _dbus_subscribe_signal(GDBusConnection *conn, const char* object_name, const char* intf_name,
323 const char* signal_name, GDBusSignalCallback signal_cb, guint *subscribe_id, void* userdata)
327 if (!conn || !object_name || !intf_name || !signal_name || !signal_cb) {
328 debug_error("Invalid Argument");
329 return MM_ERROR_INVALID_ARGUMENT;
332 debug_log("Dbus subscirbe signal with Obj'%s' Intf'%s' sig'%s'", object_name, intf_name, signal_name);
334 subs_id = g_dbus_connection_signal_subscribe(conn, NULL, intf_name, signal_name, object_name, \
335 NULL , G_DBUS_SIGNAL_FLAGS_NONE , signal_cb, userdata, NULL );
338 debug_error ("g_dbus_connection_signal_subscribe() failed ");
339 return MM_ERROR_SOUND_INTERNAL;
342 *subscribe_id = subs_id;
345 return MM_ERROR_NONE;
348 static void _dbus_unsubscribe_signal(GDBusConnection *conn, guint subs_id)
350 if (!conn || !subs_id) {
351 debug_error("Invalid Argument");
354 g_dbus_connection_signal_unsubscribe(conn, subs_id);
357 static GDBusConnection* _dbus_get_connection(GBusType bustype)
359 static GDBusConnection *conn_system = NULL;
360 static GDBusConnection *conn_session = NULL;
362 if (bustype == G_BUS_TYPE_SYSTEM) {
364 debug_log("Already connected to system bus");
366 debug_log("Get new connection on system bus");
367 conn_system = g_bus_get_sync(bustype, NULL, NULL);
370 } else if (bustype == G_BUS_TYPE_SESSION) {
372 debug_log("Already connected to session bus");
374 debug_log("Get new connection on session bus");
375 conn_session = g_bus_get_sync(bustype, NULL, NULL);
379 debug_error("Invalid bus type");
385 static void _dbus_disconnect(GDBusConnection* conn)
388 g_object_unref(conn);
392 /******************************************************************************************
393 Simple Functions For Communicate with Sound-Server
394 ******************************************************************************************/
396 static int _dbus_method_call_to(int dbus_to, int method_type, GVariant *args, GVariant **result)
398 int ret = MM_ERROR_NONE;
399 GDBusConnection *conn = NULL;
400 const char *bus_name, *object, *interface;
402 if (method_type < 0 || method_type > METHOD_CALL_MAX) {
403 debug_error("Invalid method type");
404 return MM_ERROR_INVALID_ARGUMENT;
407 if (dbus_to == DBUS_TO_SOUND_SERVER) {
408 bus_name = BUS_NAME_SOUND_SERVER;
409 object = OBJECT_SOUND_SERVER;
410 interface = INTERFACE_SOUND_SERVER;
411 } else if (dbus_to == DBUS_TO_PULSE_MODULE_DEVICE_MANAGER) {
412 bus_name = BUS_NAME_PULSEAUDIO;
413 object = OBJECT_PULSE_MODULE_DEVICE_MANAGER;
414 interface = INTERFACE_PULSE_MODULE_DEVICE_MANAGER;
415 } else if (dbus_to == DBUS_TO_PULSE_MODULE_STREAM_MANAGER) {
416 bus_name = BUS_NAME_PULSEAUDIO;
417 object = OBJECT_PULSE_MODULE_STREAM_MANAGER;
418 interface = INTERFACE_PULSE_MODULE_STREAM_MANAGER;
419 } else if (dbus_to == DBUS_TO_PULSE_MODULE_POLICY) {
420 bus_name = BUS_NAME_PULSEAUDIO;
421 object = OBJECT_PULSE_MODULE_POLICY;
422 interface = INTERFACE_PULSE_MODULE_POLICY;
423 } else if (dbus_to == DBUS_TO_FOCUS_SERVER) {
424 bus_name = BUS_NAME_FOCUS_SERVER;
425 object = OBJECT_FOCUS_SERVER;
426 interface = INTERFACE_FOCUS_SERVER;
428 debug_error("Invalid case, dbus_to %d", dbus_to);
429 return MM_ERROR_SOUND_INTERNAL;
432 if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
433 if((ret = _dbus_method_call(conn, bus_name,
436 g_methods[method_type].name,
437 args, result)) != MM_ERROR_NONE) {
438 debug_error("Dbus Call on Client Error");
442 debug_error("Get Dbus Connection Error");
443 return MM_ERROR_SOUND_INTERNAL;
446 return MM_ERROR_NONE;
449 static void _dbus_signal_callback (GDBusConnection *connection,
450 const gchar *sender_name,
451 const gchar *object_path,
452 const gchar *interface_name,
453 const gchar *signal_name,
457 struct user_callback* user_cb = (struct user_callback*) user_data;
459 if (!user_cb || !user_cb->cb) {
460 debug_error("User callback data Null");
464 if (user_cb->sig_type < 0 || user_cb->sig_type >= SIGNAL_MAX) {
465 debug_error("Wrong Signal Type");
470 debug_error("Parameter Null");
474 debug_log("Signal(%s.%s) Received , Let's call Wrapper-Callback", interface_name, signal_name);
476 if (user_cb->sig_type == SIGNAL_VOLUME_CHANGED) {
477 char *volume_type_str = NULL, *direction = NULL;
478 unsigned int volume_level;
480 g_variant_get(params, "(&s&su)", &direction, &volume_type_str, &volume_level);
481 ((mm_sound_volume_changed_wrapper_cb)(user_cb->cb))(direction, volume_type_str, volume_level, user_cb->userdata);
482 } else if (user_cb->sig_type == SIGNAL_DEVICE_CONNECTED) {
483 const char *name = NULL, *device_type = NULL;
484 gboolean is_connected = FALSE;
485 int device_id, io_direction, state;
487 g_variant_get(params, "((i&sii&s)b)", &device_id, &device_type, &io_direction,
488 &state, &name, &is_connected);
489 ((mm_sound_device_connected_wrapper_cb)(user_cb->cb))(device_id, device_type, io_direction, state, name, is_connected, user_cb->userdata);
490 } else if (user_cb->sig_type == SIGNAL_DEVICE_INFO_CHANGED) {
491 const char *name = NULL, *device_type = NULL;
492 int changed_device_info_type = 0;
493 int device_id, io_direction, state;
495 g_variant_get(params, "((i&sii&s)i)", &device_id, &device_type, &io_direction,
496 &state, &name, &changed_device_info_type);
497 ((mm_sound_device_info_changed_wrapper_cb)(user_cb->cb))(device_id, device_type, io_direction, state, name, changed_device_info_type, user_cb->userdata);
498 } else if (user_cb->sig_type == SIGNAL_FOCUS_CHANGED) {
499 } else if (user_cb->sig_type == SIGNAL_FOCUS_WATCH) {
500 } else if (user_cb->sig_type == SIGNAL_TEST) {
502 g_variant_get(params, "(i)", &test_var);
503 ((mm_sound_test_cb)(user_cb->cb))(test_var, user_cb->userdata);
504 } else if (user_cb->sig_type == SIGNAL_PLAY_FILE_END) {
505 int ended_handle = 0;
506 g_variant_get(params, "(i)", &ended_handle);
507 ((mm_sound_stop_callback_wrapper_func)(user_cb->cb))(ended_handle, user_cb->userdata);
511 static int _dbus_signal_subscribe_to(int dbus_to, sound_server_signal_t signaltype, void *cb, void *userdata, int mask, unsigned int *subs_id)
513 GDBusConnection *conn = NULL;
515 struct user_callback *user_cb = NULL;
516 const char *object, *interface;
519 debug_error("Callback data Null");
520 return MM_ERROR_INVALID_ARGUMENT;
523 if (signaltype < 0 || signaltype >= SIGNAL_MAX) {
524 debug_error("Wrong Signal Type");
525 return MM_ERROR_INVALID_ARGUMENT;
528 if (!(user_cb = g_malloc0(sizeof(struct user_callback)))) {
529 debug_error("Allocate Memory for User CB data Failed");
530 return MM_ERROR_SOUND_INTERNAL;
533 user_cb->sig_type = signaltype;
535 user_cb->userdata = userdata;
536 user_cb->mask = mask;
539 if (dbus_to == DBUS_TO_SOUND_SERVER) {
540 object = OBJECT_SOUND_SERVER;
541 interface = INTERFACE_SOUND_SERVER;
542 } else if (dbus_to == DBUS_TO_PULSE_MODULE_DEVICE_MANAGER) {
543 object = OBJECT_PULSE_MODULE_DEVICE_MANAGER;
544 interface = INTERFACE_PULSE_MODULE_DEVICE_MANAGER;
545 } else if (dbus_to == DBUS_TO_PULSE_MODULE_STREAM_MANAGER) {
546 object = OBJECT_PULSE_MODULE_STREAM_MANAGER;
547 interface = INTERFACE_PULSE_MODULE_STREAM_MANAGER;
548 } else if (dbus_to == DBUS_TO_PULSE_MODULE_POLICY) {
549 object = OBJECT_PULSE_MODULE_POLICY;
550 interface = INTERFACE_PULSE_MODULE_POLICY;
552 debug_error("Invalid case, dbus_to %d", dbus_to);
553 return MM_ERROR_SOUND_INTERNAL;
557 if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
558 if(_dbus_subscribe_signal(conn, object, interface, g_signals[signaltype].name,
559 _dbus_signal_callback, &_subs_id, user_cb) != MM_ERROR_NONE) {
560 debug_error("Dbus Subscribe on Client Error");
561 return MM_ERROR_SOUND_INTERNAL;
564 *subs_id = (unsigned int)_subs_id;
567 debug_error("Get Dbus Connection Error");
568 return MM_ERROR_SOUND_INTERNAL;
570 return MM_ERROR_NONE;
573 static int _dbus_signal_unsubscribe(unsigned int subs_id)
575 GDBusConnection *conn = NULL;
577 if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
578 _dbus_unsubscribe_signal(conn, (guint) subs_id);
580 debug_error("Get Dbus Connection Error");
581 return MM_ERROR_SOUND_INTERNAL;
584 return MM_ERROR_NONE;
587 static int _pulseaudio_dbus_set_property(pulseaudio_property_t property, GVariant* args, GVariant **result)
589 int ret = MM_ERROR_NONE;
590 GDBusConnection *conn = NULL;
592 if (property < 0 || property > PULSEAUDIO_PROP_MAX) {
593 debug_error("Invalid property [%d]", property);
594 return MM_ERROR_INVALID_ARGUMENT;
598 debug_error("Invalid args");
599 return MM_ERROR_INVALID_ARGUMENT;
602 if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
603 if((ret = _dbus_set_property(conn, BUS_NAME_PULSEAUDIO, OBJECT_PULSE_MODULE_POLICY, INTERFACE_PULSE_MODULE_POLICY,
604 g_pulseaudio_properties[property].name, args, result)) != MM_ERROR_NONE) {
605 debug_error("Dbus Call on Client Error");
609 debug_error("Get Dbus Connection Error");
610 return MM_ERROR_SOUND_INTERNAL;
613 return MM_ERROR_NONE;
616 static int _pulseaudio_dbus_get_property(pulseaudio_property_t property, GVariant **result)
618 int ret = MM_ERROR_NONE;
619 GDBusConnection *conn = NULL;
621 if (property < 0 || property > PULSEAUDIO_PROP_MAX) {
622 debug_error("Invalid property [%d]", property);
623 return MM_ERROR_INVALID_ARGUMENT;
626 if ((conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
627 if((ret = _dbus_get_property(conn, BUS_NAME_PULSEAUDIO, OBJECT_PULSE_MODULE_POLICY, INTERFACE_PULSE_MODULE_POLICY,
628 g_pulseaudio_properties[property].name, result)) != MM_ERROR_NONE) {
629 debug_error("Dbus Call on Client Error");
633 debug_error("Get Dbus Connection Error");
634 return MM_ERROR_SOUND_INTERNAL;
637 return MM_ERROR_NONE;
640 /******************************************************************************************
641 Implementation of each dbus client code (Construct Params,..)
642 ******************************************************************************************/
644 int mm_sound_client_dbus_add_test_callback(mm_sound_test_cb func, void* user_data, unsigned int *subs_id)
646 int ret = MM_ERROR_NONE;
650 if ((ret = _dbus_signal_subscribe_to(DBUS_TO_SOUND_SERVER, SIGNAL_TEST, func, user_data, 0, subs_id)) != MM_ERROR_NONE) {
651 debug_error("add test callback failed");
658 int mm_sound_client_dbus_remove_test_callback(unsigned int subs_id)
660 int ret = MM_ERROR_NONE;
663 if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
664 debug_error("remove test callback failed");
671 int mm_sound_client_dbus_test(int a, int b, int *get)
673 int ret = MM_ERROR_NONE;
675 GVariant *params = NULL, *result = NULL;
679 params = g_variant_new("(ii)", a, b);
681 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_TEST, params, &result)) != MM_ERROR_NONE) {
682 debug_error("dbus test call failed");
686 debug_error("Construct Param for method call failed");
687 return MM_ERROR_SOUND_INTERNAL;
691 g_variant_get(result, "(i)", &reply);
692 debug_log("reply : %d", reply);
695 debug_error("reply null");
700 g_variant_unref(result);
706 int mm_sound_client_dbus_get_current_connected_device_list(int device_flags, GList** device_list)
708 int ret = MM_ERROR_NONE;
709 GVariant *result = NULL, *child = NULL;
712 mm_sound_device_t* device_item;
713 const gchar *device_name_tmp = NULL, *device_type_tmp = NULL;
718 debug_error("Invalid Parameter, device_list null");
719 ret = MM_ERROR_INVALID_ARGUMENT;
723 params = g_variant_new("(i)", device_flags);
726 if ((ret = _dbus_method_call_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, METHOD_CALL_GET_CONNECTED_DEVICE_LIST, params, &result)) != MM_ERROR_NONE) {
727 debug_error("Get current connected device list failed");
731 debug_error("Construct Param for get current connected device failed");
732 return MM_ERROR_SOUND_INTERNAL;
735 child = g_variant_get_child_value(result, 0);
736 g_variant_iter_init(&iter, child);
738 device_item = g_malloc0(sizeof(mm_sound_device_t));
739 if (device_item && g_variant_iter_loop(&iter, "(i&sii&s)", &device_item->id, &device_type_tmp, &device_item->io_direction, &device_item->state, &device_name_tmp)) {
740 MMSOUND_STRNCPY(device_item->name, device_name_tmp, MAX_DEVICE_NAME_NUM);
741 MMSOUND_STRNCPY(device_item->type, device_type_tmp, MAX_DEVICE_TYPE_STR_LEN);
742 *device_list = g_list_append(*device_list, device_item);
743 debug_log("Added device id(%d) type(%17s) direction(%d) state(%d) name(%s)", device_item->id, device_item->type,device_item->io_direction, device_item->state, device_item->name);
753 g_variant_unref(result);
759 int mm_sound_client_dbus_add_device_connected_callback(int device_flags, mm_sound_device_connected_wrapper_cb func, void* user_data, unsigned int *subs_id)
761 int ret = MM_ERROR_NONE;
765 if ((ret = _dbus_signal_subscribe_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, SIGNAL_DEVICE_CONNECTED, func, user_data, device_flags, subs_id)) != MM_ERROR_NONE) {
766 debug_error("add device connected callback failed");
773 int mm_sound_client_dbus_remove_device_connected_callback(unsigned int subs_id)
775 int ret = MM_ERROR_NONE;
778 if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
779 debug_error("remove device connected callback failed");
786 int mm_sound_client_dbus_add_device_info_changed_callback(int device_flags, mm_sound_device_info_changed_wrapper_cb func, void* user_data, unsigned int *subs_id)
788 int ret = MM_ERROR_NONE;
791 if ((ret = _dbus_signal_subscribe_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, SIGNAL_DEVICE_INFO_CHANGED, func, user_data, device_flags, subs_id)) != MM_ERROR_NONE) {
792 debug_error("Add device info changed callback failed");
799 int mm_sound_client_dbus_remove_device_info_changed_callback(unsigned int subs_id)
801 int ret = MM_ERROR_NONE;
804 if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
805 debug_error("remove device info changed callback failed");
812 int mm_sound_client_dbus_is_bt_a2dp_on (bool *connected, char** bt_name)
814 int ret = MM_ERROR_NONE;
815 GVariant* result = NULL;
817 gchar* _bt_name = NULL;
821 if((ret = _dbus_method_call_to(DBUS_TO_PULSE_MODULE_DEVICE_MANAGER, METHOD_CALL_GET_BT_A2DP_STATUS, NULL, &result)) != MM_ERROR_NONE) {
824 g_variant_get(result, "(bs)", &_connected, &_bt_name);
826 *connected = _connected;
827 *bt_name = (_connected)? _bt_name : NULL;
831 g_variant_unref(result);
837 int mm_sound_client_dbus_set_volume_by_type(const char *volume_type, const unsigned int volume_level)
839 int ret = MM_ERROR_NONE;
840 char *reply = NULL, *direction = "out";
841 GVariant *params = NULL, *result = NULL;
845 params = g_variant_new("(ssu)", direction, volume_type, volume_level);
847 if ((ret = _dbus_method_call_to(DBUS_TO_PULSE_MODULE_STREAM_MANAGER, METHOD_CALL_SET_VOLUME_LEVEL, params, &result)) != MM_ERROR_NONE) {
848 debug_error("dbus test call failed");
852 debug_error("Construct Param for method call failed");
853 return MM_ERROR_SOUND_INTERNAL;
857 g_variant_get(result, "(&s)", &reply);
858 debug_log("reply : %s", reply);
859 if (!strcmp(reply, "STREAM_MANAGER_RETURN_ERROR"))
860 ret = MM_ERROR_SOUND_INTERNAL;
862 debug_error("reply null");
867 g_variant_unref(result);
873 int mm_sound_client_dbus_add_volume_changed_callback(mm_sound_volume_changed_wrapper_cb func, void* user_data, unsigned int *subs_id)
875 int ret = MM_ERROR_NONE;
879 if ((ret = _dbus_signal_subscribe_to(DBUS_TO_PULSE_MODULE_STREAM_MANAGER, SIGNAL_VOLUME_CHANGED, func, user_data, 0, subs_id)) != MM_ERROR_NONE) {
880 debug_error("Add Volume changed callback failed");
888 int mm_sound_client_dbus_remove_volume_changed_callback(unsigned int subs_id)
890 int ret = MM_ERROR_NONE;
893 if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
894 debug_error("Remove Volume changed callback failed");
901 int mm_sound_client_dbus_get_audio_path(mm_sound_device_in *device_in, mm_sound_device_out *device_out)
903 int ret = MM_ERROR_NONE;
904 GVariant *result = NULL;
908 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_GET_AUDIO_PATH, NULL, &result)) != MM_ERROR_NONE) {
909 debug_error("add device connected callback failed");
913 g_variant_get(result, "(ii)", device_in, device_out );
917 g_variant_unref(result);
923 int mm_sound_client_dbus_play_tone(int tone, int repeat, int volume, int volume_config,
924 int session_type, int session_options, int client_pid,
925 bool enable_session, int *codechandle, char *stream_type, int stream_index)
927 int ret = MM_ERROR_NONE;
929 GVariant* params = NULL, *result = NULL;
930 gboolean _enable_session = enable_session;
933 debug_error("Param for play is null");
934 return MM_ERROR_INVALID_ARGUMENT;
939 params = g_variant_new("(iiiiiiibsi)", tone, repeat, volume,
940 volume_config, session_type, session_options, client_pid , _enable_session, stream_type, stream_index);
942 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_DTMF, params, &result)) != MM_ERROR_NONE) {
943 debug_error("dbus play tone failed");
947 debug_error("Construct Param for method call failed");
951 g_variant_get(result, "(i)", &handle);
952 debug_log("handle : %d", handle);
953 *codechandle = handle;
955 debug_error("reply null");
960 g_variant_unref(result);
968 int mm_sound_client_dbus_play_tone_with_stream_info(int client_pid, int tone, char *stream_type, int stream_index, int volume, int repeat, int *codechandle)
970 int ret = MM_ERROR_NONE;
972 GVariant* params = NULL, *result = NULL;
977 debug_error("Param for play is null");
978 return MM_ERROR_INVALID_ARGUMENT;
981 params = g_variant_new("(iiiisi)", tone, repeat, volume, client_pid, stream_type, stream_index);
983 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_DTMF_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
984 debug_error("dbus play tone failed");
988 debug_error("Construct Param for method call failed");
992 g_variant_get(result, "(i)", &handle);
993 debug_log("handle : %d", handle);
994 *codechandle = handle;
996 debug_error("reply null");
1001 g_variant_unref(result);
1009 int mm_sound_client_dbus_play_sound(const char* filename, int tone, int repeat, int volume, int volume_config,
1010 int priority, int session_type, int session_options, int client_pid, int handle_route,
1011 bool enable_session, int *codechandle, char *stream_type, int stream_index)
1013 int ret = MM_ERROR_NONE;
1015 GVariant* params = NULL, *result = NULL;
1016 gboolean _enable_session = enable_session;
1018 if (!filename || !codechandle) {
1019 debug_error("Param for play is null");
1020 return MM_ERROR_INVALID_ARGUMENT;
1025 params = g_variant_new("(siiiiiiiiibsi)", filename, tone, repeat, volume,
1026 volume_config, priority, session_type, session_options, client_pid, handle_route, _enable_session, stream_type, stream_index);
1028 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_FILE_START, params, &result)) != MM_ERROR_NONE) {
1029 debug_error("dbus play file failed");
1033 debug_error("Construct Param for method call failed");
1037 g_variant_get(result, "(i)", &handle);
1038 debug_log("handle : %d", handle);
1039 *codechandle = handle;
1041 debug_error("reply null");
1046 g_variant_unref(result);
1052 int mm_sound_client_dbus_play_sound_with_stream_info(const char* filename, int repeat, int volume,
1053 int priority, int client_pid, int handle_route, int *codechandle, char *stream_type, int stream_index)
1055 int ret = MM_ERROR_NONE;
1057 GVariant* params = NULL, *result = NULL;
1059 if (!filename || !codechandle) {
1060 debug_error("Param for play is null");
1061 return MM_ERROR_INVALID_ARGUMENT;
1066 params = g_variant_new("(siiiiisi)", filename, repeat, volume,
1067 priority, client_pid, handle_route, stream_type, stream_index);
1069 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_FILE_START_WITH_STREAM_INFO, params, &result)) != MM_ERROR_NONE) {
1070 debug_error("dbus play file failed");
1074 debug_error("Construct Param for method call failed");
1078 g_variant_get(result, "(i)", &handle);
1079 debug_log("handle : %d", handle);
1080 *codechandle = handle;
1082 debug_error("reply null");
1087 g_variant_unref(result);
1096 int mm_sound_client_dbus_stop_sound(int handle)
1098 int ret = MM_ERROR_NONE;
1099 GVariant *result = NULL;
1103 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_PLAY_FILE_STOP, g_variant_new("(i)", handle), &result)) != MM_ERROR_NONE) {
1104 debug_error("dbus stop file playing failed");
1110 g_variant_unref(result);
1116 int mm_sound_client_dbus_clear_focus(int pid)
1118 int ret = MM_ERROR_NONE;
1119 GVariant *result = NULL;
1123 if ((ret = _dbus_method_call_to(DBUS_TO_SOUND_SERVER, METHOD_CALL_CLEAR_FOCUS, g_variant_new("(i)", pid), &result)) != MM_ERROR_NONE) {
1124 debug_error("dbus clear focus failed");
1128 g_variant_unref(result);
1134 int mm_sound_client_dbus_is_route_available(mm_sound_route route, bool *is_available)
1136 int ret = MM_ERROR_NONE;
1139 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1145 int mm_sound_client_dbus_foreach_available_route_cb(mm_sound_available_route_cb avail_cb, void *user_data)
1147 int ret = MM_ERROR_NONE;
1150 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1156 int mm_sound_client_dbus_set_active_route(mm_sound_route route, bool need_broadcast)
1158 int ret = MM_ERROR_NONE;
1161 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1167 int mm_sound_client_dbus_get_active_device(mm_sound_device_in *device_in, mm_sound_device_out *device_out)
1169 int ret = MM_ERROR_NONE;
1172 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1178 int mm_sound_client_dbus_add_play_sound_end_callback(mm_sound_stop_callback_wrapper_func stop_cb, void* userdata, unsigned int *subs_id)
1180 int ret = MM_ERROR_NONE;
1184 if ((ret = _dbus_signal_subscribe_to(DBUS_TO_SOUND_SERVER, SIGNAL_PLAY_FILE_END, stop_cb, userdata, 0, subs_id)) != MM_ERROR_NONE) {
1185 debug_error("add play sound end callback failed");
1193 int mm_sound_client_dbus_remove_play_sound_end_callback(unsigned int subs_id)
1195 int ret = MM_ERROR_NONE;
1198 if ((ret = _dbus_signal_unsubscribe(subs_id)) != MM_ERROR_NONE) {
1199 debug_error("Remove Play File End callback failed");
1206 int mm_sound_client_dbus_add_active_device_changed_callback(const char *name, mm_sound_active_device_changed_cb func, void* user_data)
1208 int ret = MM_ERROR_NONE;
1211 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1217 int mm_sound_client_dbus_remove_active_device_changed_callback(const char *name)
1219 int ret = MM_ERROR_NONE;
1222 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1228 int mm_sound_client_dbus_add_available_route_changed_callback(mm_sound_available_route_changed_cb func, void* user_data)
1230 int ret = MM_ERROR_NONE;
1233 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1239 int mm_sound_client_dbus_remove_available_route_changed_callback(void)
1241 int ret = MM_ERROR_NONE;
1244 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1250 int mm_sound_client_dbus_set_sound_path_for_active_device(mm_sound_device_out device_out, mm_sound_device_in device_in)
1252 int ret = MM_ERROR_NONE;
1255 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1261 int mm_sound_client_dbus_set_active_route_auto(void)
1263 int ret = MM_ERROR_NONE;
1266 ret = MM_ERROR_SOUND_NOT_SUPPORTED_OPERATION;
1272 /*------------------------------------------ FOCUS --------------------------------------------------*/
1275 #ifdef SUPPORT_CONTAINER
1277 char* _get_cookie(int cookie_size)
1280 char* cookie = NULL;
1282 if (security_server_get_cookie_size() != cookie_size) {
1283 debug_error ("[Security] security_server_get_cookie_size() != COOKIE_SIZE(%d)\n", cookie_size);
1287 cookie = (char*)malloc (cookie_size);
1289 retval = security_server_request_cookie (cookie, cookie_size);
1290 if (retval == SECURITY_SERVER_API_SUCCESS) {
1291 debug_msg ("[Security] security_server_request_cookie() returns [%d]\n", retval);
1293 debug_error ("[Security] security_server_request_cookie() returns [%d]\n", retval);
1299 static GVariant* _get_cookie_variant ()
1302 GVariantBuilder builder;
1303 char* cookie = NULL;
1305 cookie = _get_cookie(COOKIE_SIZE);
1310 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1311 for (i = 0; i < COOKIE_SIZE; i++)
1312 g_variant_builder_add(&builder, "y", cookie[i]);
1315 return g_variant_builder_end(&builder);
1318 #endif /* USE_SECURITY */
1319 #endif /* SUPPORT_CONTAINER */
1321 int mm_sound_client_dbus_register_focus(int id, int instance, const char *stream_type, mm_sound_focus_changed_cb callback, bool is_for_session, void* user_data)
1323 int ret = MM_ERROR_NONE;
1324 GVariant* params = NULL, *result = NULL;
1325 #ifdef SUPPORT_CONTAINER
1326 char container[128];
1331 #ifdef SUPPORT_CONTAINER
1333 params = g_variant_new("(@ayiisb)", _get_cookie_variant(), instance, id, stream_type, is_for_session);
1334 #else /* USE_SECURITY */
1335 gethostname(container, sizeof(container));
1336 debug_error("container = %s", container);
1337 params = g_variant_new("(siisb)", container, instance, id, stream_type, is_for_session);
1338 #endif /* USE_SECURITY */
1340 #else /* SUPPORT_CONTAINER */
1341 params = g_variant_new("(iisb)", instance, id, stream_type, is_for_session);
1343 #endif /* SUPPORT_CONTAINER */
1346 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_REGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
1347 debug_error("dbus register focus failed");
1350 debug_error("Construct Param for method call failed");
1353 if(ret != MM_ERROR_NONE)
1354 g_variant_get(result, "(i)", &ret);
1356 g_variant_unref(result);
1364 int mm_sound_client_dbus_unregister_focus(int instance, int id, bool is_for_session)
1366 int ret = MM_ERROR_NONE;
1367 GVariant* params = NULL, *result = NULL;
1371 params = g_variant_new("(iib)", instance, id, is_for_session);
1373 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_UNREGISTER_FOCUS, params, &result)) != MM_ERROR_NONE) {
1374 debug_error("dbus unregister focus failed");
1377 debug_error("Construct Param for method call failed");
1380 if (ret != MM_ERROR_NONE)
1381 g_variant_get(result, "(i)", &ret);
1383 g_variant_unref(result);
1390 int mm_sound_client_dbus_acquire_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session)
1392 int ret = MM_ERROR_NONE;
1393 GVariant* params = NULL, *result = NULL;
1397 params = g_variant_new("(iiisb)", instance, id, type, option, is_for_session);
1399 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_ACQUIRE_FOCUS, params, &result)) != MM_ERROR_NONE) {
1400 debug_error("dbus acquire focus failed");
1403 debug_error("Construct Param for method call failed");
1406 if (ret != MM_ERROR_NONE)
1407 g_variant_get(result, "(i)", &ret);
1409 g_variant_unref(result);
1415 int mm_sound_client_dbus_release_focus(int instance, int id, mm_sound_focus_type_e type, const char *option, bool is_for_session)
1417 int ret = MM_ERROR_NONE;
1418 GVariant* params = NULL, *result = NULL;
1422 params = g_variant_new("(iiisb)", instance, id, type, option, is_for_session);
1424 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_RELEASE_FOCUS, params, &result)) != MM_ERROR_NONE) {
1425 debug_error("dbus release focus failed");
1428 debug_error("Construct Param for method call failed");
1431 if (ret != MM_ERROR_NONE)
1432 g_variant_get(result, "(i)", &ret);
1434 g_variant_unref(result);
1440 int mm_sound_client_dbus_set_focus_watch_callback(int instance, int handle, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, bool is_for_session, void* user_data)
1442 int ret = MM_ERROR_NONE;
1443 GVariant* params = NULL, *result = NULL;
1444 #ifdef SUPPORT_CONTAINER
1445 char container[128];
1449 #ifdef SUPPORT_CONTAINER
1451 params = g_variant_new("(@ayiiib)", _get_cookie_variant(), instance, handle, type, is_for_session);
1452 #else /* USE_SECURITY */
1453 gethostname(container, sizeof(container));
1454 debug_error("container = %s", container);
1455 params = g_variant_new("(siiib)", container, instance, handle, type, is_for_session);
1456 #endif /* USE_SECURITY */
1458 #else /* SUPPORT_CONTAINER */
1459 params = g_variant_new("(iiib)", instance, handle, type, is_for_session);
1460 #endif /* SUPPORT_CONTAINER */
1463 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_WATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
1464 debug_error("dbus set watch focus failed");
1467 debug_error("Construct Param for method call failed");
1470 if (ret != MM_ERROR_NONE)
1471 g_variant_get(result, "(i)", &ret);
1473 g_variant_unref(result);
1480 int mm_sound_client_dbus_unset_focus_watch_callback(int focus_tid, int handle, bool is_for_session)
1482 int ret = MM_ERROR_NONE;
1483 GVariant* params = NULL, *result = NULL;
1487 params = g_variant_new("(iib)", focus_tid, handle, is_for_session);
1489 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_UNWATCH_FOCUS, params, &result)) != MM_ERROR_NONE) {
1490 debug_error("dbus unset watch focus failed");
1493 debug_error("Construct Param for method call failed");
1495 if (ret != MM_ERROR_NONE)
1496 g_variant_get(result, "(i)", &ret);
1498 g_variant_unref(result);
1505 int mm_sound_client_dbus_emergent_exit_focus(int exit_pid)
1507 int ret = MM_ERROR_NONE;
1508 GVariant* params = NULL, *result = NULL;
1512 params = g_variant_new("(i)", exit_pid);
1514 if ((ret = _dbus_method_call_to(DBUS_TO_FOCUS_SERVER, METHOD_CALL_EMERGENT_EXIT_FOCUS, params, &result)) != MM_ERROR_NONE) {
1515 debug_error("dbus emergent exit focus failed");
1519 debug_error("Construct Param for method call failed");
1523 if (ret != MM_ERROR_NONE)
1524 g_variant_get(result, "(i)", &ret);
1526 g_variant_unref(result);
1532 #endif /* USE_FOCUS */
1533 /*------------------------------------------ FOCUS --------------------------------------------------*/
1535 int mm_sound_client_dbus_initialize(void)
1537 int ret = MM_ERROR_NONE;
1545 int mm_sound_client_dbus_finalize(void)
1547 int ret = MM_ERROR_NONE;