Remove dlog prints on signal handler / dotnet cleanup
[platform/core/multimedia/libmm-sound.git] / common / mm_sound_dbus.c
1
2 #include <gio/gio.h>
3 #include <stdlib.h>
4
5 #include <mm_error.h>
6 #include <mm_debug.h>
7
8 #include "../include/mm_sound_dbus.h"
9 #include "../include/mm_sound_intf.h"
10
11 struct callback_data {
12         mm_sound_dbus_callback user_cb;
13         void *user_data;
14         mm_sound_dbus_userdata_free free_func;
15 };
16
17 struct dbus_path {
18         char *bus_name;
19         char *object;
20         char *interface;
21 };
22
23 const struct dbus_path g_paths[AUDIO_PROVIDER_MAX] = {
24         [AUDIO_PROVIDER_SOUND_SERVER] = {
25                 .bus_name = "org.tizen.SoundServer",
26                 .object = "/org/tizen/SoundServer1",
27                 .interface = "org.tizen.SoundServer1"
28         },
29         [AUDIO_PROVIDER_FOCUS_SERVER] = {
30                 .bus_name = "org.tizen.FocusServer",
31                 .object = "/org/tizen/FocusServer1",
32                 .interface = "org.tizen.FocusServer1"
33         },
34         [AUDIO_PROVIDER_DEVICE_MANAGER] = {
35                 .bus_name = "org.pulseaudio.Server",
36                 .object = "/org/pulseaudio/DeviceManager",
37                 .interface = "org.pulseaudio.DeviceManager"
38         },
39         [AUDIO_PROVIDER_STREAM_MANAGER] = {
40                 .bus_name = "org.pulseaudio.Server",
41                 .object = "/org/pulseaudio/StreamManager",
42                 .interface = "org.pulseaudio.StreamManager"
43         },
44         [AUDIO_PROVIDER_AUDIO_CLIENT] = {
45                 .bus_name = "org.tizen.AudioClient",
46                 .object = "/org/tizen/AudioClient1",
47                 .interface = "org.tizen.AudioClient1"
48         }
49 };
50
51 const mm_sound_dbus_method_info_t g_methods[AUDIO_METHOD_MAX] = {
52         [AUDIO_METHOD_TEST] = {
53                 .name = "MethodTest1",
54         },
55         [AUDIO_METHOD_PLAY_FILE_START] = {
56                 .name = "PlayFileStart",
57         },
58         [AUDIO_METHOD_PLAY_FILE_START_WITH_STREAM_INFO] = {
59                 .name = "PlayFileStartWithStreamInfo",
60         },
61         [AUDIO_METHOD_PLAY_FILE_STOP] = {
62                 .name = "PlayFileStop",
63         },
64         [AUDIO_METHOD_PLAY_DTMF] = {
65                 .name = "PlayDTMF",
66         },
67         [AUDIO_METHOD_PLAY_DTMF_WITH_STREAM_INFO] = {
68                 .name = "PlayDTMFWithStreamInfo",
69         },
70         [AUDIO_METHOD_CLEAR_FOCUS] = {
71                 .name = "ClearFocus",
72         },
73         [AUDIO_METHOD_SET_VOLUME_LEVEL] = {
74                 .name = "SetVolumeLevel",
75         },
76         [AUDIO_METHOD_GET_CONNECTED_DEVICE_LIST] = {
77                 .name = "GetConnectedDeviceList",
78         },
79         [AUDIO_METHOD_GET_DEVICE_BY_ID] = {
80                 .name = "GetDeviceById",
81         },
82         [AUDIO_METHOD_IS_STREAM_ON_DEVICE] = {
83                 .name = "IsStreamOnDevice",
84         },
85         [AUDIO_METHOD_GET_UNIQUE_ID] = {
86                 .name = "GetUniqueId",
87         },
88         [AUDIO_METHOD_REGISTER_FOCUS] = {
89                 .name = "RegisterFocus",
90         },
91         [AUDIO_METHOD_UNREGISTER_FOCUS] = {
92                 .name = "UnregisterFocus",
93         },
94         [AUDIO_METHOD_SET_FOCUS_REACQUISITION] = {
95                 .name = "SetFocusReacquisition",
96         },
97         [AUDIO_METHOD_GET_ACQUIRED_FOCUS_STREAM_TYPE] = {
98                 .name = "GetAcquiredFocusStreamType",
99         },
100         [AUDIO_METHOD_ACQUIRE_FOCUS] = {
101                 .name = "AcquireFocus",
102         },
103         [AUDIO_METHOD_RELEASE_FOCUS] = {
104                 .name = "ReleaseFocus",
105         },
106         [AUDIO_METHOD_UPDATE_STREAM_FOCUS_STATUS] = {
107                 .name = "UpdateFocusStatusByFocusId",
108         },
109         [AUDIO_METHOD_WATCH_FOCUS] = {
110                 .name = "WatchFocus",
111         },
112         [AUDIO_METHOD_UNWATCH_FOCUS] = {
113                 .name = "UnwatchFocus",
114         },
115         [AUDIO_METHOD_DELIVER_FOCUS] = {
116                 .name = "DeliverFocus",
117         },
118         [AUDIO_METHOD_SET_FILTER] = {
119                 .name = "SetFilter",
120         },
121         [AUDIO_METHOD_UNSET_FILTER] = {
122                 .name = "UnsetFilter",
123         },
124         [AUDIO_METHOD_CONTROL_FILTER] = {
125                 .name = "ControlFilter",
126         },
127 };
128
129 const mm_sound_dbus_signal_info_t g_events[AUDIO_EVENT_MAX] = {
130         [AUDIO_EVENT_TEST] = {
131                 .name = "SignalTest1",
132         },
133         [AUDIO_EVENT_PLAY_FILE_END] = {
134                 .name = "PlayFileEnd",
135         },
136         [AUDIO_EVENT_VOLUME_CHANGED] = {
137                 .name = "VolumeChanged",
138         },
139         [AUDIO_EVENT_DEVICE_CONNECTED] = {
140                 .name = "DeviceConnected",
141         },
142         [AUDIO_EVENT_DEVICE_INFO_CHANGED] = {
143                 .name = "DeviceInfoChanged",
144         },
145         [AUDIO_EVENT_DEVICE_STATE_CHANGED] = {
146                 .name = "DeviceStateChanged",
147         },
148         [AUDIO_EVENT_DEVICE_RUNNING_CHANGED] = {
149                 .name = "DeviceRunningChanged",
150         },
151         [AUDIO_EVENT_FOCUS_CHANGED] = {
152                 .name = "FocusChanged",
153         },
154         [AUDIO_EVENT_FOCUS_WATCH] = {
155                 .name = "FocusWatch",
156         },
157         [AUDIO_EVENT_EMERGENT_EXIT] = {
158                 .name = "EmergentExit",
159         },
160         [AUDIO_EVENT_CLIENT_SUBSCRIBED] = {
161                 .name = "ClientSubscribed",
162         },
163         [AUDIO_EVENT_CLIENT_HANDLED] = {
164                 .name = "ClientSignalHandled",
165         }
166 };
167
168 /* Only For error types which is currently being used in server-side */
169 static const GDBusErrorEntry mm_sound_error_entries[] = {
170         {MM_ERROR_OUT_OF_MEMORY, "org.tizen.multimedia.OutOfMemory"},
171         {MM_ERROR_OUT_OF_STORAGE, "org.tizen.multimedia.OutOfStorage"},
172         {MM_ERROR_INVALID_ARGUMENT, "org.tizen.multimedia.InvalidArgument"},
173         {MM_ERROR_POLICY_INTERNAL, "org.tizen.multimedia.PolicyInternal"},
174         {MM_ERROR_NOT_SUPPORT_API, "org.tizen.multimedia.NotSupportAPI"},
175         {MM_ERROR_POLICY_BLOCKED, "org.tizen.multimedia.PolicyBlocked"},
176         {MM_ERROR_END_OF_FILE, "org.tizen.multimedia.EndOfFile"},
177         {MM_ERROR_COMMON_OUT_OF_RANGE, "org.tizen.multimedia.common.OutOfRange"},
178         {MM_ERROR_COMMON_UNKNOWN, "org.tizen.multimedia.common.Unknown"},
179         {MM_ERROR_COMMON_NO_FREE_SPACE, "org.tizen.multimedia.common.NoFreeSpace"},
180         {MM_ERROR_SOUND_INTERNAL, "org.tizen.multimedia.audio.Internal"},
181         {MM_ERROR_SOUND_INVALID_STATE, "org.tizen.multimedia.audio.InvalidState"},
182         {MM_ERROR_SOUND_NO_FREE_SPACE, "org.tizen.multimedia.audio.NoFreeSpace"},
183         {MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE, "org.tizen.multimedia.audio.UnsupportedMediaType"},
184         {MM_ERROR_SOUND_INVALID_POINTER, "org.tizen.multimedia.audio.InvalidPointer"},
185         {MM_ERROR_SOUND_INVALID_FILE, "org.tizen.multimedia.audio.InvalidFile"},
186         {MM_ERROR_SOUND_FILE_NOT_FOUND, "org.tizen.multimedia.audio.FileNotFound"},
187         {MM_ERROR_SOUND_NO_DATA, "org.tizen.multimedia.audio.NoData"},
188         {MM_ERROR_SOUND_INVALID_PATH, "org.tizen.multimedia.audio.InvalidPath"},
189         {MM_ERROR_SOUND_PERMISSION_DENIED, "org.freedesktop.DBus.Error.AccessDenied"},
190 };
191
192
193 /******************************************************************************************
194                 Wrapper Functions of GDbus
195 ******************************************************************************************/
196
197 static int _parse_error_msg(char *full_err_msg, char **err_name, char **err_msg)
198 {
199         char *save_p = NULL, *domain, *_err_name, *_err_msg;
200
201         if (!(domain = strtok_r(full_err_msg, ":", &save_p))) {
202                 debug_error("get domain failed");
203                 return -1;
204         }
205         if (!(_err_name = strtok_r(NULL, ":", &save_p))) {
206                 debug_error("get err name failed");
207                 return -1;
208         }
209         if (!(_err_msg = strtok_r(NULL, ":", &save_p))) {
210                 debug_error("get err msg failed");
211                 return -1;
212         }
213
214         *err_name = _err_name;
215         *err_msg = _err_msg;
216
217         return 0;
218 }
219
220 static int _convert_error_name(const char *err_name)
221 {
222         int i = 0;
223
224         debug_error("error name is [%s]", err_name);
225
226         for (i = 0; i < G_N_ELEMENTS(mm_sound_error_entries); i++) {
227                 if (!strcmp(mm_sound_error_entries[i].dbus_error_name, err_name))
228                         return mm_sound_error_entries[i].error_code;
229         }
230
231         return MM_ERROR_COMMON_UNKNOWN;
232 }
233
234 static int _dbus_method_call(GDBusConnection *conn, const char *bus_name, const char *object, const char *intf,
235                                                         const char *method, GVariant *args, GVariant **result)
236 {
237         int ret = MM_ERROR_NONE;
238         GError *err = NULL;
239         GVariant *dbus_reply = NULL;
240
241         if (!conn || !object || !intf || !method) {
242                 debug_error("Invalid Argument");
243                 if (!conn)
244                         debug_error("conn null");
245                 if (!object)
246                         debug_error("object null");
247                 if (!intf)
248                         debug_error("intf null");
249                 if (!method)
250                         debug_error("method null");
251                 return MM_ERROR_INVALID_ARGUMENT;
252         }
253
254         debug_log("Dbus call with obj'%s' intf'%s' method'%s'", object, intf, method);
255
256         dbus_reply = g_dbus_connection_call_sync(conn, bus_name, object , intf,
257                                                                                         method, args ,
258                                                                                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
259
260         if (!dbus_reply || err) {
261                 char *err_name = NULL, *err_msg = NULL;
262                 debug_error("Method Call '%s.%s' Failed, %s", intf, method, err ? err->message : NULL);
263                 ret = MM_ERROR_SOUND_INTERNAL;
264                 if (err) {
265                         if (_parse_error_msg(err->message, &err_name, &err_msg) < 0) {
266                                 debug_error("failed to parse error message");
267                                 g_error_free(err);
268                                 return MM_ERROR_SOUND_INTERNAL;
269                         }
270                         ret = _convert_error_name(err_name);
271                 }
272                 g_error_free(err);
273         } else {
274                 debug_log("Method Call '%s.%s' Success", intf, method);
275         }
276
277         *result = dbus_reply;
278
279         return ret;
280 }
281
282 static int _dbus_subscribe_signal(GDBusConnection *conn, const char *object_name, const char *intf_name,
283                                                                 const char *signal_name, GDBusSignalCallback signal_cb, guint *subscribe_id,
284                                                                 void *userdata, GDestroyNotify freefunc)
285 {
286         guint subs_id = 0;
287
288         if (!conn || !object_name || !intf_name || !signal_name || !signal_cb) {
289                 debug_error("Invalid Argument");
290                 return MM_ERROR_INVALID_ARGUMENT;
291         }
292
293         debug_log("Dbus subscirbe signal with Obj'%s' Intf'%s' sig'%s'", object_name, intf_name, signal_name);
294
295         subs_id = g_dbus_connection_signal_subscribe(conn, NULL, intf_name, signal_name, object_name,
296                                                                                                 NULL, G_DBUS_SIGNAL_FLAGS_NONE , signal_cb, userdata, freefunc);
297
298         if (!subs_id) {
299                 debug_error("g_dbus_connection_signal_subscribe() failed ");
300                 return MM_ERROR_SOUND_INTERNAL;
301         }
302         if (subscribe_id)
303                 *subscribe_id = subs_id;
304
305         return MM_ERROR_NONE;
306 }
307
308 static void _dbus_unsubscribe_signal(GDBusConnection *conn, guint subs_id)
309 {
310         if (!conn || !subs_id) {
311                 debug_error("Invalid Argument");
312                 return;
313         }
314
315         g_dbus_connection_signal_unsubscribe(conn, subs_id);
316 }
317
318 static GDBusConnection * _dbus_get_connection(GBusType bustype)
319 {
320         static GDBusConnection *conn_system = NULL;
321         static GDBusConnection *conn_session = NULL;
322         GError *err = NULL;
323
324         if (bustype == G_BUS_TYPE_SYSTEM) {
325                 if (conn_system) {
326 #ifndef TIZEN_TV
327                         debug_log("Already connected to system bus");
328 #endif
329                 } else {
330 #ifndef TIZEN_TV
331                         debug_log("Get new connection on system bus");
332 #endif
333                         conn_system = g_bus_get_sync(bustype, NULL, &err);
334                         if (!conn_system || err) {
335 #ifndef TIZEN_TV
336                                 debug_error("g_dbus_get_sync() error (%s)", err ? err->message : NULL);
337 #endif
338                                 g_error_free(err);
339                                 return NULL;
340                         }
341                 }
342                 return conn_system;
343         } else if (bustype == G_BUS_TYPE_SESSION) {
344                 if (conn_session) {
345 #ifndef TIZEN_TV
346                         debug_log("Already connected to session bus");
347 #endif
348                 } else {
349 #ifndef TIZEN_TV
350                         debug_log("Get new connection on session bus");
351 #endif
352                         conn_session = g_bus_get_sync(bustype, NULL, &err);
353                         if (!conn_session || err) {
354 #ifndef TIZEN_TV
355                                 debug_error("g_dbus_get_sync() error (%s)", err ? err->message : NULL);
356 #endif
357                                 g_error_free(err);
358                                 return NULL;
359                         }
360                 }
361                 return conn_session;
362         } else {
363 #ifndef TIZEN_TV
364                 debug_error("Invalid bus type");
365 #endif
366                 return NULL;
367         }
368
369 }
370
371 /******************************************************************************************
372                 Simple Functions For Communicate with Sound-Server
373 ******************************************************************************************/
374
375 EXPORT_API
376 int mm_sound_dbus_method_call_to(audio_provider_t provider, audio_method_t method_type, GVariant *args, GVariant **result)
377 {
378         int ret = MM_ERROR_NONE;
379         GDBusConnection *conn = NULL;
380
381         if (method_type >= AUDIO_METHOD_MAX) {
382                 debug_error("Invalid method type : %d", method_type);
383                 return MM_ERROR_INVALID_ARGUMENT;
384         }
385         if (provider >= AUDIO_PROVIDER_MAX) {
386                 debug_error("Invalid provider : %d", provider);
387                 return MM_ERROR_INVALID_ARGUMENT;
388         }
389
390         if (!(conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
391                 debug_error("Get Dbus Connection Error");
392                 return MM_ERROR_SOUND_INTERNAL;
393         }
394
395         if ((ret = _dbus_method_call(conn, g_paths[provider].bus_name,
396                                                                 g_paths[provider].object,
397                                                                 g_paths[provider].interface,
398                                                                 g_methods[method_type].name,
399                                                                 args, result)) != MM_ERROR_NONE) {
400                 debug_error("Dbus Call on Client Error");
401         }
402
403         return ret;
404 }
405
406 /* This callback only transform signal-callback to dbus non-related form (mm_sound_dbus_callback) */
407 static void _dbus_signal_callback(GDBusConnection *connection,
408                                                                 const gchar *sender_name,
409                                                                 const gchar *object_path,
410                                                                 const gchar *interface_name,
411                                                                 const gchar *signal_name,
412                                                                 GVariant *params,
413                                                                 gpointer userdata)
414 {
415         struct callback_data *cb_data = (struct callback_data *)userdata;
416
417         debug_log("Signal(%s.%s) Received, Let's call Wrapper-Callback", interface_name, signal_name);
418
419         if (!strcmp(signal_name, g_events[AUDIO_EVENT_VOLUME_CHANGED].name))
420                 (cb_data->user_cb)(AUDIO_EVENT_VOLUME_CHANGED, params, cb_data->user_data);
421         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_DEVICE_CONNECTED].name))
422                 (cb_data->user_cb)(AUDIO_EVENT_DEVICE_CONNECTED, params, cb_data->user_data);
423         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_DEVICE_INFO_CHANGED].name))
424                 (cb_data->user_cb)(AUDIO_EVENT_DEVICE_INFO_CHANGED, params, cb_data->user_data);
425         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_DEVICE_STATE_CHANGED].name))
426                 (cb_data->user_cb)(AUDIO_EVENT_DEVICE_STATE_CHANGED, params, cb_data->user_data);
427         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_FOCUS_CHANGED].name))
428                 (cb_data->user_cb)(AUDIO_EVENT_FOCUS_CHANGED, params, cb_data->user_data);
429         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_FOCUS_WATCH].name))
430                 (cb_data->user_cb)(AUDIO_EVENT_FOCUS_WATCH, params, cb_data->user_data);
431         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_PLAY_FILE_END].name))
432                 (cb_data->user_cb)(AUDIO_EVENT_PLAY_FILE_END, params, cb_data->user_data);
433         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_EMERGENT_EXIT].name))
434                 (cb_data->user_cb)(AUDIO_EVENT_EMERGENT_EXIT, params, cb_data->user_data);
435         else if (!strcmp(signal_name, g_events[AUDIO_EVENT_DEVICE_RUNNING_CHANGED].name))
436                 (cb_data->user_cb)(AUDIO_EVENT_DEVICE_RUNNING_CHANGED, params, cb_data->user_data);
437 }
438
439 static void callback_data_free_func(gpointer data)
440 {
441         struct callback_data *cb_data = (struct callback_data *)data;
442
443         if (cb_data->free_func)
444                 cb_data->free_func(cb_data->user_data);
445         g_free(cb_data);
446 }
447
448 EXPORT_API
449 int mm_sound_dbus_signal_subscribe_to(audio_provider_t provider, audio_event_t event, mm_sound_dbus_callback callback,
450                                                                         void *userdata, mm_sound_dbus_userdata_free freefunc, unsigned *subs_id)
451 {
452         GDBusConnection *conn = NULL;
453         guint _subs_id = 0;
454         struct callback_data *cb_data = NULL;
455
456         if (!callback) {
457                 debug_error("Callback is Null");
458                 return MM_ERROR_INVALID_ARGUMENT;
459         }
460
461         if (event >= AUDIO_EVENT_MAX) {
462                 debug_error("Wrong event Type : %d", event);
463                 return MM_ERROR_INVALID_ARGUMENT;
464         }
465
466         if (provider >= AUDIO_PROVIDER_MAX) {
467                 debug_error("Invalid provider : %d", provider);
468                 return MM_ERROR_INVALID_ARGUMENT;
469         }
470
471         if (!(conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
472                 debug_error("Get Dbus Connection Error");
473                 return MM_ERROR_SOUND_INTERNAL;
474         }
475
476         if (!(cb_data = (struct callback_data*)g_malloc0(sizeof(struct callback_data)))) {
477                 debug_error("Allocate for callback data failed");
478                 return MM_ERROR_SOUND_INTERNAL;
479         }
480
481         cb_data->user_cb = callback;
482         cb_data->user_data = userdata;
483         cb_data->free_func = freefunc;
484
485         if (_dbus_subscribe_signal(conn, g_paths[provider].object, g_paths[provider].interface, g_events[event].name,
486                                                         _dbus_signal_callback, &_subs_id, cb_data, callback_data_free_func) != MM_ERROR_NONE) {
487                 debug_error("Dbus Subscribe on Client Error");
488                 goto fail;
489         }
490         if (subs_id)
491                 *subs_id = (unsigned int)_subs_id;
492
493         return MM_ERROR_NONE;
494
495 fail:
496         free(cb_data);
497         return MM_ERROR_SOUND_INTERNAL;
498 }
499
500 EXPORT_API
501 int mm_sound_dbus_signal_unsubscribe(unsigned int subs_id)
502 {
503         GDBusConnection *conn = NULL;
504
505         if (!(conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
506                 debug_error("Get Dbus Connection Error");
507                 return MM_ERROR_SOUND_INTERNAL;
508         }
509
510         _dbus_unsubscribe_signal(conn, (guint)subs_id);
511
512         return MM_ERROR_NONE;
513 }
514
515 EXPORT_API
516 int mm_sound_dbus_emit_signal(audio_provider_t provider, audio_event_t event, GVariant *param)
517 {
518         GDBusConnection *conn;
519         GError *err = NULL;
520         gboolean dbus_ret;
521
522         if (event >= AUDIO_EVENT_MAX) {
523 #ifndef TIZEN_TV
524                 debug_error("emit signal failed, invalid argument, event_type(%d)", event);
525 #endif
526                 return MM_ERROR_INVALID_ARGUMENT;
527         }
528
529         if (!(conn = _dbus_get_connection(G_BUS_TYPE_SYSTEM))) {
530 #ifndef TIZEN_TV
531                 debug_error("Get Dbus Connection Error");
532 #endif
533                 return MM_ERROR_SOUND_INTERNAL;
534         }
535
536         dbus_ret = g_dbus_connection_emit_signal(conn,
537                                                   NULL, g_paths[provider].object,
538                                                   g_paths[provider].interface, g_events[event].name,
539                                                   param, &err);
540         if (!dbus_ret || err) {
541 #ifndef TIZEN_TV
542                 debug_error("g_dbus_connection_emit_signal() error (%s)", err ? err->message : NULL);
543 #endif
544                 g_error_free(err);
545                 return MM_ERROR_SOUND_INTERNAL;
546         }
547         g_dbus_connection_flush_sync(conn, NULL, NULL);
548
549 #ifndef TIZEN_TV
550         debug_msg("emit signal for [%s] success", g_events[event].name);
551 #endif
552         return MM_ERROR_NONE;
553 }
554
555 EXPORT_API
556 int mm_sound_dbus_get_event_name(audio_event_t event, const char **event_name)
557 {
558         if (!event_name) {
559                 debug_error("Invalid Parameter, event_name NULL");
560                 return MM_ERROR_INVALID_ARGUMENT;
561         }
562         if (event >= AUDIO_EVENT_MAX) {
563                 debug_error("invalid event : %d", event);
564                 return MM_ERROR_INVALID_ARGUMENT;
565         }
566
567         *event_name = g_events[event].name;
568         return MM_ERROR_NONE;
569 }
570
571 EXPORT_API
572 int mm_sound_dbus_get_method_name(audio_method_t method, const char **method_name)
573 {
574         if (!method_name) {
575                 debug_error("Invalid Parameter, method_name NULL");
576                 return MM_ERROR_INVALID_ARGUMENT;
577         }
578         if (method >= AUDIO_METHOD_MAX) {
579                 debug_error("invalid method : %d", method);
580                 return MM_ERROR_INVALID_ARGUMENT;
581         }
582
583         *method_name = g_methods[method].name;
584         return MM_ERROR_NONE;
585 }