Use smart pointer using g_autoptr
[platform/core/api/wav-player.git] / src / wav_player_private.c
old mode 100755 (executable)
new mode 100644 (file)
index 8de2dff..f06b8f8
 #define PA_SOUND_PLAYER_METHOD_NAME_SOUND_STOP         "SoundStop"
 #define PA_SOUND_PLAYER_SIGNAL_EOS                     "EOS"
 
-struct dbus_cb_data {
-       GDBusConnection *conn;
+typedef struct dbus_cb_data {
        int handle;
        guint subs_id;
        wav_player_playback_completed_cb cb;
        void *user_data;
-};
+} dbus_cb_data_s;
 
 static int __convert_dbus_error(const char *error_msg)
 {
@@ -55,17 +54,25 @@ static int __convert_dbus_error(const char *error_msg)
        return WAV_PLAYER_ERROR_INVALID_OPERATION;
 }
 
+static void __weak_notify_cb(gpointer data, GObject *where_the_object_was)
+{
+       LOGD("object(%p) destroyed, data(%p)", where_the_object_was, data);
+}
+
 static GDBusConnection *__get_dbus_connection(void)
 {
        GDBusConnection *conn = NULL;
-       GError *err = NULL;
+       g_autoptr(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 NULL;
        }
 
+       /* For Debugging Purpose */
+       g_object_weak_ref(G_OBJECT(conn), __weak_notify_cb, NULL);
+
        return conn;
 }
 
@@ -77,28 +84,37 @@ static void __internal_complete_cb(GDBusConnection *connection,
                                        GVariant *params,
                                        gpointer userdata)
 {
-       int handle;
-       struct dbus_cb_data *dbus_data = (struct dbus_cb_data *)userdata;
-
-       g_variant_get(params, "(i)", &handle);
+       gint handle = -1;
+       gboolean stopped_by_user = FALSE;
+       dbus_cb_data_s *dbus_data = (dbus_cb_data_s *)userdata;
 
        if (!dbus_data) {
-               LOGE("dbus data is null. handle(%d)", handle);
+               LOGE("dbus data is null");
                return;
        }
 
-       if (handle == dbus_data->handle) {
-               g_dbus_connection_signal_unsubscribe(dbus_data->conn, dbus_data->subs_id);
-               g_object_unref(dbus_data->conn);
+       g_variant_get(params, "(ib)", &handle, &stopped_by_user);
+       LOGI("Incoming/expected handle(%d/%d), id(%u), callback(%p), stopped_by_user(%d)",
+               handle, dbus_data->handle, dbus_data->subs_id, dbus_data->cb, stopped_by_user);
+
+       if (handle != dbus_data->handle)
+               return;
 
-               LOGD("user callback for handle(%d) cb(%p)", handle, dbus_data->cb);
+       if (!stopped_by_user) {
+               LOGI("Invoking user callback(%p) for handle(%d)", dbus_data->cb, handle);
                dbus_data->cb(handle, dbus_data->user_data);
-               g_free(dbus_data);
        }
+
+       LOGI("user callback returned");
+
+       g_dbus_connection_signal_unsubscribe(connection, dbus_data->subs_id);
+       g_object_unref(connection);
+
+       g_free(dbus_data);
 }
 
 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)
+                       wav_player_playback_completed_cb callback, void *user_data, bool stop_others, int *id)
 {
        int ret = WAV_PLAYER_ERROR_NONE;
        char m_path[PATH_MAX];
@@ -107,10 +123,10 @@ int _wav_play_sound(const char *path, sound_stream_info_h stream_info, unsigned
        bool result = false;
 
        int handle;
-       GError *err = NULL;
-       GVariant *reply = NULL;
-       GDBusConnection *conn = NULL;
-       struct dbus_cb_data *dbus_cb_data = NULL;
+       g_autoptr(GDBusConnection) conn = NULL;
+       g_autoptr(GError) err = NULL;
+       g_autoptr(GVariant) reply = NULL;
+       dbus_cb_data_s *dbus_cb_data = NULL;
 
        if (path == NULL || stream_info == NULL) {
                LOGE("invalid params");
@@ -156,53 +172,104 @@ int _wav_play_sound(const char *path, sound_stream_info_h stream_info, unsigned
                        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),
+                       g_variant_new("(siisib)", m_path, loop_count == 0 ? -1 : loop_count,
+                                       getpid(), stream_type, stream_id, (gboolean)stop_others),
                        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;
        }
 
        g_variant_get(reply, "(i)", &handle);
-       g_variant_unref(reply);
        if (id)
                *id = handle;
 
        LOGI("handle : %d", handle);
 
        if (callback) {
-               dbus_cb_data = g_new0(struct dbus_cb_data, 1);
-               dbus_cb_data->conn = conn;
+               dbus_cb_data = g_new0(dbus_cb_data_s, 1);
                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) {
+               dbus_cb_data->subs_id = g_dbus_connection_signal_subscribe(
+                               g_object_ref(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 == 0) {
                        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);
        }
 
        return WAV_PLAYER_ERROR_NONE;
 }
 
+//LCOV_EXCL_START
+int _wav_play_sound_simple(const char *path, const char *stream_role)
+{
+       char m_path[PATH_MAX];
+       int handle;
+       g_autoptr(GDBusConnection) conn = NULL;
+       g_autoptr(GError) err = NULL;
+       g_autoptr(GVariant) reply = NULL;
+
+       if (!path || !stream_role) {
+               LOGE("invalid params path(%p), stream_role(%p)", path, stream_role);
+               return WAV_PLAYER_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGI("path(%s), stream_role(%s)", path, stream_role);
+
+       /* FIXME : need extraction of duplicated path validation code */
+       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;
+       }
+
+       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("(siisib)", m_path, 1,
+                                                                                                         getpid(), stream_role, -1, FALSE),
+                                                                               NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+       if (!reply) {
+               if (err) {
+                       LOGE("g_dbus_connection_call_sync error (%s)", err->message);
+                       return __convert_dbus_error(err->message);
+               }
+               return WAV_PLAYER_ERROR_INVALID_OPERATION;
+       }
+
+       g_variant_get(reply, "(i)", &handle);
+
+       LOGI("handle : %d", handle);
+
+       return WAV_PLAYER_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
+
 int _wav_stop_sound(int id)
 {
-       GDBusConnection *conn = NULL;
-       GError *err = NULL;
-       GVariant *reply = NULL;
+       g_autoptr(GDBusConnection) conn = NULL;
+       g_autoptr(GError) err = NULL;
+       g_autoptr(GVariant) reply = NULL;
 
        LOGI("handle(%d)", id);
 
@@ -216,20 +283,11 @@ int _wav_stop_sound(int id)
                                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;
+               return __convert_dbus_error(err->message);
        }
 
-       g_variant_unref(reply);
-
        LOGI("stop sound. handle(%d)", id);
 
        return WAV_PLAYER_ERROR_NONE;