Send dbus IPC directly to SoundPlayer 00/233800/18 accepted/tizen_6.0_unified_hotfix tizen_6.0_hotfix accepted/tizen/6.0/unified/20201030.121955 accepted/tizen/6.0/unified/hotfix/20201103.004240 accepted/tizen/6.0/unified/hotfix/20201103.051309 accepted/tizen/unified/20200617.055848 submit/tizen/20200615.061755 submit/tizen/20200616.024212 submit/tizen/20200616.100606 submit/tizen_6.0/20201029.205102 submit/tizen_6.0_hotfix/20201102.192502 submit/tizen_6.0_hotfix/20201103.114802 tizen_6.0.m2_release
authorJaechul Lee <jcsing.lee@samsung.com>
Tue, 19 May 2020 07:27:09 +0000 (16:27 +0900)
committerJaechul Lee <jcsing.lee@samsung.com>
Fri, 5 Jun 2020 05:38:55 +0000 (14:38 +0900)
[Version] 0.3.3
[Issue Type] Improvement

Change-Id: I899bbf511f64d677c07c529823397e07ae234e47
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
CMakeLists.txt
capi-media-wav-player.pc.in
include/wav_player_private.h
packaging/capi-media-wav-player.spec
src/wav_player.c
src/wav_player_private.c
test/CMakeLists.txt

index b8ab841..9e7d1e1 100644 (file)
@@ -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}")
index 1997d91..1508489 100644 (file)
@@ -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}
 
index 2b87c06..83772b1 100644 (file)
@@ -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
 }
index 18af4d2..dc5fa32 100755 (executable)
@@ -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.
index 0c53709..1f28594 100755 (executable)
@@ -18,8 +18,6 @@
 
 #include <sound_manager.h>
 #include <sound_manager_internal.h>
-#include <mm_sound.h>
-#include <mm_sound_private.h>
 #include <stdio.h>
 #include <limits.h>
 #include <string.h>
 #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);
 }
 
index 904bcf5..8de2dff 100755 (executable)
 
 #define LOG_TAG "TIZEN_N_WAV_PLAYER"
 
-#include <mm_sound.h>
-#include <mm_sound_private.h>
 #include <stdio.h>
 #include <limits.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 #include <dlog.h>
 #include <stdlib.h>
+#include <gio/gio.h>
+#include <glib.h>
 #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;
 }
index dbd3830..e66cd18 100644 (file)
@@ -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})