2 * Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #define LOG_TAG "TIZEN_N_WAV_PLAYER"
28 #include "wav_player_private.h"
30 #define PA_BUS_NAME "org.pulseaudio.Server"
31 #define PA_SOUND_PLAYER_OBJECT_PATH "/org/pulseaudio/SoundPlayer"
32 #define PA_SOUND_PLAYER_INTERFACE "org.pulseaudio.SoundPlayer"
34 #define PA_SOUND_PLAYER_METHOD_NAME_SOUND_PLAY "SoundPlay"
35 #define PA_SOUND_PLAYER_METHOD_NAME_SOUND_STOP "SoundStop"
36 #define PA_SOUND_PLAYER_SIGNAL_EOS "EOS"
39 GDBusConnection *conn;
42 wav_player_playback_completed_cb cb;
46 static int __convert_dbus_error(const char *error_msg)
49 if (strstr(error_msg, "UnsupportedMediaType"))
50 return WAV_PLAYER_ERROR_FORMAT_NOT_SUPPORTED;
51 else if (strstr(error_msg, "InvalidArgument"))
52 return WAV_PLAYER_ERROR_INVALID_PARAMETER;
55 return WAV_PLAYER_ERROR_INVALID_OPERATION;
58 static GDBusConnection *__get_dbus_connection(void)
60 GDBusConnection *conn = NULL;
63 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
65 LOGE("g_bus_get_sync() error (%s)", err->message);
72 static void __internal_complete_cb(GDBusConnection *connection,
73 const gchar *sender_name,
74 const gchar *object_path,
75 const gchar *interface_name,
76 const gchar *signal_name,
81 struct dbus_cb_data *dbus_data = (struct dbus_cb_data *)userdata;
83 g_variant_get(params, "(i)", &handle);
86 LOGE("dbus data is null. handle(%d)", handle);
90 if (handle == dbus_data->handle) {
91 g_dbus_connection_signal_unsubscribe(dbus_data->conn, dbus_data->subs_id);
92 g_object_unref(dbus_data->conn);
94 LOGD("user callback for handle(%d) cb(%p)", handle, dbus_data->cb);
95 dbus_data->cb(handle, dbus_data->user_data);
100 int _wav_play_sound(const char *path, sound_stream_info_h stream_info, unsigned loop_count,
101 wav_player_playback_completed_cb callback, void *user_data, int *id)
103 int ret = WAV_PLAYER_ERROR_NONE;
104 char m_path[PATH_MAX];
105 char *stream_type = NULL;
111 GVariant *reply = NULL;
112 GDBusConnection *conn = NULL;
113 struct dbus_cb_data *dbus_cb_data = NULL;
115 if (path == NULL || stream_info == NULL) {
116 LOGE("invalid params");
117 return WAV_PLAYER_ERROR_INVALID_PARAMETER;
120 LOGI("path(%s), loop(%u), cb(%p) user_data(%p)", path, loop_count, callback, user_data);
123 if (path[0] != '/' && getcwd(m_path, PATH_MAX) != NULL)
124 strncat(m_path, "/", PATH_MAX - strlen(m_path) - 1);
126 strncat(m_path, path, PATH_MAX - strlen(m_path) - 1);
127 if (access(m_path, R_OK) != 0) {
129 strerror_r(errno, str_error, sizeof(str_error));
130 LOGE("file [%s] doesn't exists : [%s][%d]", m_path, str_error, errno);
131 return WAV_PLAYER_ERROR_INVALID_OPERATION;
134 ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_WAV_PLAYER, &result);
135 if (!result || ret) {
136 LOGE("stream info is not available. ret(0x%x), result(%d)", ret, result);
137 return WAV_PLAYER_ERROR_NOT_SUPPORTED_TYPE;
140 ret = sound_manager_get_type_from_stream_information(stream_info, &stream_type);
142 LOGE("can't get stream type. ret(0x%x)", ret);
143 return WAV_PLAYER_ERROR_INVALID_OPERATION;
146 ret = sound_manager_get_index_from_stream_information(stream_info, &stream_id);
148 LOGE("can't get stream index. ret(0x%x)", ret);
149 return WAV_PLAYER_ERROR_INVALID_OPERATION;
152 if (!(conn = __get_dbus_connection()))
153 return WAV_PLAYER_ERROR_INVALID_OPERATION;
155 reply = g_dbus_connection_call_sync(conn, PA_BUS_NAME,
156 PA_SOUND_PLAYER_OBJECT_PATH,
157 PA_SOUND_PLAYER_INTERFACE,
158 PA_SOUND_PLAYER_METHOD_NAME_SOUND_PLAY,
159 g_variant_new("(siisi)", m_path, loop_count == 0 ? -1 : loop_count,
160 getpid(), stream_type, stream_id),
161 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
163 LOGE("g_dbus_connection_call_sync error (%s)", err->message);
164 ret = __convert_dbus_error(err->message);
166 g_object_unref(conn);
170 g_variant_get(reply, "(i)", &handle);
171 g_variant_unref(reply);
175 LOGI("handle : %d", handle);
178 dbus_cb_data = g_new0(struct dbus_cb_data, 1);
179 dbus_cb_data->conn = conn;
180 dbus_cb_data->handle = handle;
181 dbus_cb_data->cb = callback;
182 dbus_cb_data->user_data = user_data;
183 dbus_cb_data->subs_id = g_dbus_connection_signal_subscribe(conn, NULL,
184 PA_SOUND_PLAYER_INTERFACE,
185 PA_SOUND_PLAYER_SIGNAL_EOS,
186 PA_SOUND_PLAYER_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
187 __internal_complete_cb, dbus_cb_data, NULL);
188 if (!dbus_cb_data->subs_id) {
189 g_object_unref(conn);
190 g_free(dbus_cb_data);
191 LOGE("g_dbus_connection_signal_subscribe() failed");
192 return WAV_PLAYER_ERROR_INVALID_OPERATION;
195 g_object_unref(conn);
198 return WAV_PLAYER_ERROR_NONE;
201 int _wav_stop_sound(int id)
203 GDBusConnection *conn = NULL;
205 GVariant *reply = NULL;
207 LOGI("handle(%d)", id);
209 if (!(conn = __get_dbus_connection()))
210 return WAV_PLAYER_ERROR_INVALID_OPERATION;
212 reply = g_dbus_connection_call_sync(conn,
214 PA_SOUND_PLAYER_OBJECT_PATH,
215 PA_SOUND_PLAYER_INTERFACE,
216 PA_SOUND_PLAYER_METHOD_NAME_SOUND_STOP,
217 g_variant_new("(i)", id),
218 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
220 g_object_unref(conn);
225 LOGE("g_dbus_connection_call_sync error (%s)", err->message);
226 ret = __convert_dbus_error(err->message);
231 g_variant_unref(reply);
233 LOGI("stop sound. handle(%d)", id);
235 return WAV_PLAYER_ERROR_NONE;