From: Jaechul Lee Date: Tue, 19 May 2020 07:27:09 +0000 (+0900) Subject: Send dbus IPC directly to SoundPlayer X-Git-Tag: accepted/tizen/6.0/unified/20201030.121955^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F00%2F233800%2F18;p=platform%2Fcore%2Fapi%2Fwav-player.git Send dbus IPC directly to SoundPlayer [Version] 0.3.3 [Issue Type] Improvement Change-Id: I899bbf511f64d677c07c529823397e07ae234e47 Signed-off-by: Jaechul Lee --- diff --git a/CMakeLists.txt b/CMakeLists.txt index b8ab841..9e7d1e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -SET(Services +SET(Services "application" "base" "content" @@ -24,7 +24,7 @@ SET(service "media") SET(submodule "wav-player") # for package file -SET(dependents "mm-sound dlog capi-base-common capi-media-sound-manager") +SET(dependents "dlog capi-base-common capi-media-sound-manager gio-2.0") SET(pc_dependents "capi-base-common capi-media-sound-manager") SET(fw_name "${project_prefix}-${service}-${submodule}") diff --git a/capi-media-wav-player.pc.in b/capi-media-wav-player.pc.in index 1997d91..1508489 100644 --- a/capi-media-wav-player.pc.in +++ b/capi-media-wav-player.pc.in @@ -9,7 +9,7 @@ includedir=/usr/include/media Name: @PC_NAME@ Description: @PACKAGE_DESCRIPTION@ Version: @VERSION@ -Requires: @PC_REQUIRED@ +Requires: @PC_REQUIRED@ Libs: -L${libdir} @PC_LDFLAGS@ Cflags: -I${includedir} diff --git a/include/wav_player_private.h b/include/wav_player_private.h index 2b87c06..83772b1 100644 --- a/include/wav_player_private.h +++ b/include/wav_player_private.h @@ -34,24 +34,10 @@ extern "C" * @brief This file contains the WAV player API */ -/** - * @addtogroup CAPI_MEDIA_WAV_PLAYER_MODULE - * @{ - */ - - -typedef struct _cb_data_ { - wav_player_playback_completed_cb cb; - void * user_data; -} _cb_data; - -/** - * @} - */ - int _convert_wav_player_error_code(const char *func, int code); -void _internal_complete_cb(void *user_data, int id); -int _start_with_stream_info(const char *path, sound_stream_info_h stream_info, unsigned int loop_count, wav_player_playback_completed_cb cb, void *user_data, int *id); +int _wav_play_sound(const char *path, sound_stream_info_h stream_info, unsigned int loop_count, + wav_player_playback_completed_cb cb, void *user_data, int *id); +int _wav_stop_sound(int id); #ifdef __cplusplus } diff --git a/packaging/capi-media-wav-player.spec b/packaging/capi-media-wav-player.spec index 18af4d2..dc5fa32 100755 --- a/packaging/capi-media-wav-player.spec +++ b/packaging/capi-media-wav-player.spec @@ -1,16 +1,16 @@ Name: capi-media-wav-player Summary: A wav player library in Tizen C API -Version: 0.3.2 +Version: 0.3.3 Release: 0 Group: Multimedia/API License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1001: capi-media-wav-player.manifest BuildRequires: cmake -BuildRequires: pkgconfig(mm-sound) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-media-sound-manager) +BuildRequires: pkgconfig(gio-2.0) %description A wav player library in Tizen C API. diff --git a/src/wav_player.c b/src/wav_player.c index 0c53709..1f28594 100755 --- a/src/wav_player.c +++ b/src/wav_player.c @@ -18,8 +18,6 @@ #include #include -#include -#include #include #include #include @@ -29,18 +27,20 @@ #include "wav_player.h" #include "wav_player_private.h" -int wav_player_start_new(const char *path, sound_stream_info_h stream_info, wav_player_playback_completed_cb callback, void *user_data, int *id) +int wav_player_start_new(const char *path, sound_stream_info_h stream_info, + wav_player_playback_completed_cb callback, void *user_data, int *id) { - return _start_with_stream_info(path, stream_info, 1, callback, user_data, id); + return _wav_play_sound(path, stream_info, 1, callback, user_data, id); } -int wav_player_start_loop(const char *path, sound_stream_info_h stream_info, unsigned int loop_count, wav_player_playback_completed_cb callback, void *user_data, int *id) +int wav_player_start_loop(const char *path, sound_stream_info_h stream_info, unsigned int loop_count, + wav_player_playback_completed_cb callback, void *user_data, int *id) { - return _start_with_stream_info(path, stream_info, loop_count, callback, user_data, id); + return _wav_play_sound(path, stream_info, loop_count, callback, user_data, id); } int wav_player_stop(int id) { - return _convert_wav_player_error_code(__func__, mm_sound_stop_sound(id)); + return _wav_stop_sound(id); } diff --git a/src/wav_player_private.c b/src/wav_player_private.c index 904bcf5..8de2dff 100755 --- a/src/wav_player_private.c +++ b/src/wav_player_private.c @@ -16,115 +16,221 @@ #define LOG_TAG "TIZEN_N_WAV_PLAYER" -#include -#include #include #include #include #include +#include #include #include +#include +#include #include "wav_player_private.h" -int _convert_wav_player_error_code(const char *func, int code) +#define PA_BUS_NAME "org.pulseaudio.Server" +#define PA_SOUND_PLAYER_OBJECT_PATH "/org/pulseaudio/SoundPlayer" +#define PA_SOUND_PLAYER_INTERFACE "org.pulseaudio.SoundPlayer" + +#define PA_SOUND_PLAYER_METHOD_NAME_SOUND_PLAY "SoundPlay" +#define PA_SOUND_PLAYER_METHOD_NAME_SOUND_STOP "SoundStop" +#define PA_SOUND_PLAYER_SIGNAL_EOS "EOS" + +struct dbus_cb_data { + GDBusConnection *conn; + int handle; + guint subs_id; + wav_player_playback_completed_cb cb; + void *user_data; +}; + +static int __convert_dbus_error(const char *error_msg) { - int ret = WAV_PLAYER_ERROR_INVALID_OPERATION; - char *errorstr = NULL; - switch (code) { - case MM_ERROR_NONE: - ret = WAV_PLAYER_ERROR_NONE; - errorstr = "ERROR_NONE"; - break; - case MM_ERROR_INVALID_ARGUMENT: - case MM_ERROR_SOUND_INVALID_POINTER: - case WAV_PLAYER_ERROR_INVALID_PARAMETER: - ret = WAV_PLAYER_ERROR_INVALID_PARAMETER; - errorstr = "INVALID_PARAMETER"; - break; - case MM_ERROR_SOUND_INTERNAL: - ret = WAV_PLAYER_ERROR_INVALID_OPERATION; - errorstr = "INVALID_OPERATION"; - break; - case MM_ERROR_SOUND_UNSUPPORTED_MEDIA_TYPE: - ret = WAV_PLAYER_ERROR_FORMAT_NOT_SUPPORTED; - errorstr = "FORMAT_NOT_SUPPORTED"; - break; - case WAV_PLAYER_ERROR_NOT_SUPPORTED_TYPE: - ret = WAV_PLAYER_ERROR_NOT_SUPPORTED_TYPE; - errorstr = "NOT_SUPPORTED_TYPE"; - break; - default: - ret = WAV_PLAYER_ERROR_INVALID_OPERATION; - errorstr = "INVALID_OPERATION"; - break; + if (error_msg) { + if (strstr(error_msg, "UnsupportedMediaType")) + return WAV_PLAYER_ERROR_FORMAT_NOT_SUPPORTED; + else if (strstr(error_msg, "InvalidArgument")) + return WAV_PLAYER_ERROR_INVALID_PARAMETER; } - LOGE("[%s] %s(0x%08x)", func, errorstr, ret); - return ret; + + return WAV_PLAYER_ERROR_INVALID_OPERATION; } -void _internal_complete_cb(void *user_data, int id) +static GDBusConnection *__get_dbus_connection(void) { - _cb_data *cb_data = (_cb_data*)user_data; - if (!cb_data) + GDBusConnection *conn = NULL; + GError *err = NULL; + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!conn) { + LOGE("g_bus_get_sync() error (%s)", err->message); + g_error_free(err); + } + + return conn; +} + +static void __internal_complete_cb(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *params, + gpointer userdata) +{ + int handle; + struct dbus_cb_data *dbus_data = (struct dbus_cb_data *)userdata; + + g_variant_get(params, "(i)", &handle); + + if (!dbus_data) { + LOGE("dbus data is null. handle(%d)", handle); return; + } + + if (handle == dbus_data->handle) { + g_dbus_connection_signal_unsubscribe(dbus_data->conn, dbus_data->subs_id); + g_object_unref(dbus_data->conn); - if (cb_data->cb) { - LOGD("user callback for handle %d call %p", id, cb_data->cb); - cb_data->cb(id, cb_data->user_data); + LOGD("user callback for handle(%d) cb(%p)", handle, dbus_data->cb); + dbus_data->cb(handle, dbus_data->user_data); + g_free(dbus_data); } - free(cb_data); } -int _start_with_stream_info(const char *path, sound_stream_info_h stream_info, unsigned loop_count, wav_player_playback_completed_cb callback, void *user_data, int *id) +int _wav_play_sound(const char *path, sound_stream_info_h stream_info, unsigned loop_count, + wav_player_playback_completed_cb callback, void *user_data, int *id) { - int ret = MM_ERROR_NONE; - int player = -1; + int ret = WAV_PLAYER_ERROR_NONE; char m_path[PATH_MAX]; - void (*_completed_cb)(void *, int); - _completed_cb = NULL; - _cb_data *cb_data = NULL; char *stream_type = NULL; int stream_id; bool result = false; - if (path == NULL || stream_info == NULL) - return _convert_wav_player_error_code(__func__, WAV_PLAYER_ERROR_INVALID_PARAMETER); + int handle; + GError *err = NULL; + GVariant *reply = NULL; + GDBusConnection *conn = NULL; + struct dbus_cb_data *dbus_cb_data = NULL; + + if (path == NULL || stream_info == NULL) { + LOGE("invalid params"); + return WAV_PLAYER_ERROR_INVALID_PARAMETER; + } + + LOGI("path(%s), loop(%u), cb(%p) user_data(%p)", path, loop_count, callback, user_data); + + m_path[0] = '\0'; + if (path[0] != '/' && getcwd(m_path, PATH_MAX) != NULL) + strncat(m_path, "/", PATH_MAX - strlen(m_path) - 1); + + strncat(m_path, path, PATH_MAX - strlen(m_path) - 1); + if (access(m_path, R_OK) != 0) { + char str_error[256]; + strerror_r(errno, str_error, sizeof(str_error)); + LOGE("file [%s] doesn't exists : [%s][%d]", m_path, str_error, errno); + return WAV_PLAYER_ERROR_INVALID_OPERATION; + } ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_WAV_PLAYER, &result); - if (!result) - return _convert_wav_player_error_code(__func__, WAV_PLAYER_ERROR_NOT_SUPPORTED_TYPE); + if (!result || ret) { + LOGE("stream info is not available. ret(0x%x), result(%d)", ret, result); + return WAV_PLAYER_ERROR_NOT_SUPPORTED_TYPE; + } ret = sound_manager_get_type_from_stream_information(stream_info, &stream_type); - if (ret) - return _convert_wav_player_error_code(__func__, ret); //LCOV_EXCL_LINE - ret = sound_manager_get_index_from_stream_information(stream_info, &stream_id); - if (ret) - return _convert_wav_player_error_code(__func__, ret); //LCOV_EXCL_LINE + if (ret) { + LOGE("can't get stream type. ret(0x%x)", ret); + return WAV_PLAYER_ERROR_INVALID_OPERATION; + } - m_path[0] = '\0'; - if (path[0] != '/') { + ret = sound_manager_get_index_from_stream_information(stream_info, &stream_id); + if (ret) { + LOGE("can't get stream index. ret(0x%x)", ret); + return WAV_PLAYER_ERROR_INVALID_OPERATION; + } - if (getcwd(m_path, PATH_MAX) != NULL) - strncat(m_path, "/", PATH_MAX - strlen(m_path) - 1); + if (!(conn = __get_dbus_connection())) + return WAV_PLAYER_ERROR_INVALID_OPERATION; + + reply = g_dbus_connection_call_sync(conn, PA_BUS_NAME, + PA_SOUND_PLAYER_OBJECT_PATH, + PA_SOUND_PLAYER_INTERFACE, + PA_SOUND_PLAYER_METHOD_NAME_SOUND_PLAY, + g_variant_new("(siisi)", m_path, loop_count == 0 ? -1 : loop_count, + getpid(), stream_type, stream_id), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (!reply) { + LOGE("g_dbus_connection_call_sync error (%s)", err->message); + ret = __convert_dbus_error(err->message); + g_error_free(err); + g_object_unref(conn); + return ret; } - strncat(m_path, path, PATH_MAX - strlen(m_path) - 1); + + g_variant_get(reply, "(i)", &handle); + g_variant_unref(reply); + if (id) + *id = handle; + + LOGI("handle : %d", handle); if (callback) { - _completed_cb = _internal_complete_cb; - cb_data = (_cb_data *)malloc(sizeof(_cb_data)); - if (cb_data == NULL) - return _convert_wav_player_error_code(__func__, WAV_PLAYER_ERROR_INVALID_OPERATION); //LCOV_EXCL_LINE - cb_data->cb = callback; - cb_data->user_data = user_data; + dbus_cb_data = g_new0(struct dbus_cb_data, 1); + dbus_cb_data->conn = conn; + dbus_cb_data->handle = handle; + dbus_cb_data->cb = callback; + dbus_cb_data->user_data = user_data; + dbus_cb_data->subs_id = g_dbus_connection_signal_subscribe(conn, NULL, + PA_SOUND_PLAYER_INTERFACE, + PA_SOUND_PLAYER_SIGNAL_EOS, + PA_SOUND_PLAYER_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + __internal_complete_cb, dbus_cb_data, NULL); + if (!dbus_cb_data->subs_id) { + g_object_unref(conn); + g_free(dbus_cb_data); + LOGE("g_dbus_connection_signal_subscribe() failed"); + return WAV_PLAYER_ERROR_INVALID_OPERATION; + } + } else { + g_object_unref(conn); } - ret = mm_sound_play_sound_with_stream_info(m_path, stream_type, stream_id, loop_count, _completed_cb , cb_data, &player); + return WAV_PLAYER_ERROR_NONE; +} + +int _wav_stop_sound(int id) +{ + GDBusConnection *conn = NULL; + GError *err = NULL; + GVariant *reply = NULL; + + LOGI("handle(%d)", id); + + if (!(conn = __get_dbus_connection())) + return WAV_PLAYER_ERROR_INVALID_OPERATION; + + reply = g_dbus_connection_call_sync(conn, + PA_BUS_NAME, + PA_SOUND_PLAYER_OBJECT_PATH, + PA_SOUND_PLAYER_INTERFACE, + PA_SOUND_PLAYER_METHOD_NAME_SOUND_STOP, + g_variant_new("(i)", id), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + + g_object_unref(conn); + + if (!reply) { + int ret; + + LOGE("g_dbus_connection_call_sync error (%s)", err->message); + ret = __convert_dbus_error(err->message); + g_error_free(err); + return ret; + } - if (ret == 0 && id != NULL) - *id = player; + g_variant_unref(reply); - if (ret != 0 && cb_data != NULL) - free(cb_data); + LOGI("stop sound. handle(%d)", id); - return _convert_wav_player_error_code(__func__, ret); + return WAV_PLAYER_ERROR_NONE; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dbd3830..e66cd18 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,7 @@ SET(fw_test "${fw_name}-test") INCLUDE(FindPkgConfig) -pkg_check_modules(${fw_test} REQUIRED mm-sound glib-2.0 gthread-2.0 capi-media-sound-manager) +pkg_check_modules(${fw_test} REQUIRED glib-2.0 gthread-2.0 capi-media-sound-manager gio-2.0) FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") MESSAGE(${flag})