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 gboolean stopped_by_user = FALSE;
82 struct dbus_cb_data *dbus_data = (struct dbus_cb_data *)userdata;
85 LOGE("dbus data is null");
89 g_variant_get(params, "(ib)", &handle, &stopped_by_user);
90 LOGI("expected handle(%d) callback(%p), incoming handle(%d), stopped_by_user(%d)",
91 dbus_data->handle, dbus_data->cb, handle, stopped_by_user);
93 if (handle != dbus_data->handle)
96 g_dbus_connection_signal_unsubscribe(dbus_data->conn, dbus_data->subs_id);
97 g_object_unref(dbus_data->conn);
99 if (!stopped_by_user) {
100 LOGI("Invoking user callback for handle(%d) cb(%p)", handle, dbus_data->cb);
101 dbus_data->cb(handle, dbus_data->user_data);
107 int _wav_play_sound(const char *path, sound_stream_info_h stream_info, unsigned loop_count,
108 wav_player_playback_completed_cb callback, void *user_data, bool stop_others, int *id)
110 int ret = WAV_PLAYER_ERROR_NONE;
111 char m_path[PATH_MAX];
112 char *stream_type = NULL;
118 GVariant *reply = NULL;
119 GDBusConnection *conn = NULL;
120 struct dbus_cb_data *dbus_cb_data = NULL;
122 if (path == NULL || stream_info == NULL) {
123 LOGE("invalid params");
124 return WAV_PLAYER_ERROR_INVALID_PARAMETER;
127 LOGI("path(%s), loop(%u), cb(%p) user_data(%p)", path, loop_count, callback, user_data);
130 if (path[0] != '/' && getcwd(m_path, PATH_MAX) != NULL)
131 strncat(m_path, "/", PATH_MAX - strlen(m_path) - 1);
133 strncat(m_path, path, PATH_MAX - strlen(m_path) - 1);
134 if (access(m_path, R_OK) != 0) {
136 strerror_r(errno, str_error, sizeof(str_error));
137 LOGE("file [%s] doesn't exists : [%s][%d]", m_path, str_error, errno);
138 return WAV_PLAYER_ERROR_INVALID_OPERATION;
141 ret = sound_manager_is_available_stream_information(stream_info, NATIVE_API_WAV_PLAYER, &result);
142 if (!result || ret) {
143 LOGE("stream info is not available. ret(0x%x), result(%d)", ret, result);
144 return WAV_PLAYER_ERROR_NOT_SUPPORTED_TYPE;
147 ret = sound_manager_get_type_from_stream_information(stream_info, &stream_type);
149 LOGE("can't get stream type. ret(0x%x)", ret);
150 return WAV_PLAYER_ERROR_INVALID_OPERATION;
153 ret = sound_manager_get_index_from_stream_information(stream_info, &stream_id);
155 LOGE("can't get stream index. ret(0x%x)", ret);
156 return WAV_PLAYER_ERROR_INVALID_OPERATION;
159 if (!(conn = __get_dbus_connection()))
160 return WAV_PLAYER_ERROR_INVALID_OPERATION;
162 reply = g_dbus_connection_call_sync(conn, PA_BUS_NAME,
163 PA_SOUND_PLAYER_OBJECT_PATH,
164 PA_SOUND_PLAYER_INTERFACE,
165 PA_SOUND_PLAYER_METHOD_NAME_SOUND_PLAY,
166 g_variant_new("(siisib)", m_path, loop_count == 0 ? -1 : loop_count,
167 getpid(), stream_type, stream_id, (gboolean)stop_others),
168 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
170 LOGE("g_dbus_connection_call_sync error (%s)", err->message);
171 ret = __convert_dbus_error(err->message);
173 g_object_unref(conn);
177 g_variant_get(reply, "(i)", &handle);
178 g_variant_unref(reply);
182 LOGI("handle : %d", handle);
185 dbus_cb_data = g_new0(struct dbus_cb_data, 1);
186 dbus_cb_data->conn = conn;
187 dbus_cb_data->handle = handle;
188 dbus_cb_data->cb = callback;
189 dbus_cb_data->user_data = user_data;
190 dbus_cb_data->subs_id = g_dbus_connection_signal_subscribe(conn, NULL,
191 PA_SOUND_PLAYER_INTERFACE,
192 PA_SOUND_PLAYER_SIGNAL_EOS,
193 PA_SOUND_PLAYER_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
194 __internal_complete_cb, dbus_cb_data, NULL);
195 if (!dbus_cb_data->subs_id) {
196 g_object_unref(conn);
197 g_free(dbus_cb_data);
198 LOGE("g_dbus_connection_signal_subscribe() failed");
199 return WAV_PLAYER_ERROR_INVALID_OPERATION;
202 g_object_unref(conn);
205 return WAV_PLAYER_ERROR_NONE;
209 int _wav_play_sound_simple(const char *path, const char *stream_role)
211 int ret = WAV_PLAYER_ERROR_NONE;
212 char m_path[PATH_MAX];
215 GVariant *reply = NULL;
216 GDBusConnection *conn = NULL;
218 if (!path || !stream_role) {
219 LOGE("invalid params path(%p), stream_role(%p)", path, stream_role);
220 return WAV_PLAYER_ERROR_INVALID_PARAMETER;
223 LOGI("path(%s), stream_role(%s)", path, stream_role);
225 /* FIXME : need extraction of duplicated path validation code */
227 if (path[0] != '/' && getcwd(m_path, PATH_MAX) != NULL)
228 strncat(m_path, "/", PATH_MAX - strlen(m_path) - 1);
230 strncat(m_path, path, PATH_MAX - strlen(m_path) - 1);
231 if (access(m_path, R_OK) != 0) {
233 strerror_r(errno, str_error, sizeof(str_error));
234 LOGE("file [%s] doesn't exists : [%s][%d]", m_path, str_error, errno);
235 return WAV_PLAYER_ERROR_INVALID_OPERATION;
238 if (!(conn = __get_dbus_connection()))
239 return WAV_PLAYER_ERROR_INVALID_OPERATION;
241 reply = g_dbus_connection_call_sync(conn, PA_BUS_NAME,
242 PA_SOUND_PLAYER_OBJECT_PATH,
243 PA_SOUND_PLAYER_INTERFACE,
244 PA_SOUND_PLAYER_METHOD_NAME_SOUND_PLAY,
245 g_variant_new("(siisib)", m_path, 1,
246 getpid(), stream_role, -1, FALSE),
247 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
250 LOGE("g_dbus_connection_call_sync error (%s)", err->message);
251 ret = __convert_dbus_error(err->message);
254 ret = WAV_PLAYER_ERROR_INVALID_OPERATION;
259 g_variant_get(reply, "(i)", &handle);
260 g_variant_unref(reply);
262 LOGI("handle : %d", handle);
265 g_object_unref(conn);
271 int _wav_stop_sound(int id)
273 GDBusConnection *conn = NULL;
275 GVariant *reply = NULL;
277 LOGI("handle(%d)", id);
279 if (!(conn = __get_dbus_connection()))
280 return WAV_PLAYER_ERROR_INVALID_OPERATION;
282 reply = g_dbus_connection_call_sync(conn,
284 PA_SOUND_PLAYER_OBJECT_PATH,
285 PA_SOUND_PLAYER_INTERFACE,
286 PA_SOUND_PLAYER_METHOD_NAME_SOUND_STOP,
287 g_variant_new("(i)", id),
288 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
290 g_object_unref(conn);
295 LOGE("g_dbus_connection_call_sync error (%s)", err->message);
296 ret = __convert_dbus_error(err->message);
301 g_variant_unref(reply);
303 LOGI("stop sound. handle(%d)", id);
305 return WAV_PLAYER_ERROR_NONE;