#define PULSEAUDIO_READY "/tmp/.pulseaudio_ready"
#endif
-#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_SIMPLE_PLAY "SimplePlay"
-
-#define KEYTONE_PATH "/tmp/keytone" /* Keytone pipe path */
-#define FILE_FULL_PATH 1024 /* File path length */
-#define ROLE_NAME_LEN 64 /* Role name length */
-#define VOLUME_GAIN_TYPE_LEN 64 /* Volume gain type length */
+#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_SIMPLE_PLAY "SimplePlay"
+#define PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP "SimpleStop"
+#define PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL "SimpleStopAll"
+#define PA_SOUND_RESPONSE_TIMEOUT 2000
+
+#define KEYTONE_PATH "/tmp/keytone"
+#define FILENAME_LEN 1024
+#define ROLE_LEN 64
+#define VOLUME_GAIN_TYPE_LEN 32
+#define METHOD_LEN 32
#define AUDIO_VOLUME_CONFIG_TYPE(vol) (vol & 0x00FF)
#define AUDIO_VOLUME_CONFIG_GAIN(vol) (vol & 0xFF00)
#define WRITE_RETRY_INTERVAL_MS 20
typedef struct ipc_data {
- char filename[FILE_FULL_PATH];
- char role[ROLE_NAME_LEN];
+ char filename[FILENAME_LEN];
+ char role[ROLE_LEN];
char volume_gain_type[VOLUME_GAIN_TYPE_LEN];
+ char method[METHOD_LEN];
} ipc_t;
-typedef enum {
- IPC_TYPE_PIPE,
- IPC_TYPE_DBUS,
-} ipc_type_t;
-
-static int _mm_sound_play_keysound(const char *filename, int volume_config, ipc_type_t ipc_type);
+static int __mm_sound_simple_pipe(const char *filename, int volume_config, const char *method);
+static int __mm_sound_simple_dbus(const char *filename, int volume_config, const char *method);
-static const char* convert_volume_type_to_role(int volume_type)
+static const char* __convert_volume_type_to_role(volume_type)
{
debug_log("volume_type(%d)", volume_type);
switch (volume_type) {
}
}
-static const char* convert_volume_gain_type_to_string(int volume_gain_type)
+static const char* __convert_volume_gain_type_to_string(int volume_gain_type)
{
debug_log("volume_gain_type(0x%x)", volume_gain_type);
switch (volume_gain_type) {
EXPORT_API
int mm_sound_play_keysound(const char *filename, int volume_config)
{
- return _mm_sound_play_keysound(filename, volume_config, IPC_TYPE_PIPE);
+ return __mm_sound_simple_pipe(filename, volume_config, PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY);
+}
+
+EXPORT_API
+int mm_sound_stop_keysound(const char *filename)
+{
+ return __mm_sound_simple_pipe(filename, 0,
+ (filename) ? PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP : PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL);
}
#ifdef USE_LWIPC
}
#endif
-static int _mm_sound_play_keysound(const char *filename, int volume_config, ipc_type_t ipc_type)
+static int __verify_input_file(const char *filename)
+{
+ if (!filename)
+ return MM_ERROR_SOUND_INVALID_FILE;
+
+ /* Check whether file exists */
+ if (access(filename, F_OK) == -1) {
+ char str_error[256];
+
+ strerror_r(errno, str_error, sizeof(str_error));
+ debug_error("file [%s] doesn't exists : [%s][%d]", filename, str_error, errno);
+
+ return MM_ERROR_SOUND_FILE_NOT_FOUND;
+ }
+
+ return MM_ERROR_NONE;
+}
+
+static int __mm_sound_simple_pipe(const char *filename, int volume_config, const char *method)
{
int ret = MM_ERROR_NONE;
- const char *role = NULL;
- const char *vol_gain_type = NULL;
int retry_remaining = MAX_WRITE_RETRY;
+ size_t size_to_write = sizeof(ipc_t);
+ ssize_t written = 0;
+ int fd = -1;
+ ipc_t data = { { 0, }, { 0, }, { 0, } };
#ifdef USE_LWIPC
if (!_mm_sound_check_pa_ready()) {
}
#endif
- if (!filename)
- return MM_ERROR_SOUND_INVALID_FILE;
+ if (!method)
+ return MM_ERROR_INVALID_ARGUMENT;
- /* Check whether file exists */
- if (access(filename, F_OK) == -1) {
- char str_error[256];
+ /* Prepare data to be send */
+ g_strlcpy(data.method, method, METHOD_LEN);
- strerror_r(errno, str_error, sizeof(str_error));
- debug_error("file [%s] doesn't exists : [%s][%d]", filename, str_error, errno);
+ if (g_strcmp0(method, PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL) != 0) {
+ ret = __verify_input_file(filename);
+ if (ret != MM_ERROR_NONE)
+ return ret;
- return MM_ERROR_SOUND_FILE_NOT_FOUND;
+ g_strlcpy(data.filename, filename, FILENAME_LEN);
}
- /* convert volume type to role/volume gain */
- role = convert_volume_type_to_role(AUDIO_VOLUME_CONFIG_TYPE(volume_config));
- if (role)
- vol_gain_type = convert_volume_gain_type_to_string(AUDIO_VOLUME_CONFIG_GAIN(volume_config));
+ if (g_strcmp0(method, PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY) == 0) {
+ g_strlcpy(data.role,
+ __convert_volume_type_to_role(AUDIO_VOLUME_CONFIG_TYPE(volume_config)),
+ ROLE_LEN);
+ g_strlcpy(data.volume_gain_type,
+ __convert_volume_gain_type_to_string(AUDIO_VOLUME_CONFIG_GAIN(volume_config)),
+ VOLUME_GAIN_TYPE_LEN);
+ }
- if (ipc_type == IPC_TYPE_PIPE) {
- size_t size_to_write = sizeof(ipc_t);
- ssize_t written = 0;
- int fd = -1;
- ipc_t data = { { 0, }, { 0, }, { 0, } };
+ debug_msg("filepath=[%s], role=[%s], volume_gain_type=[%s], method=[%s]",
+ data.filename, data.role, data.volume_gain_type, data.method);
+
+ /* Open PIPE */
+ fd = open(KEYTONE_PATH, O_WRONLY | O_NONBLOCK);
+ if (fd == -1) {
+ char str_error[256];
+
+ strerror_r(errno, str_error, sizeof(str_error));
+ debug_error("Fail to open pipe: [%s][%d]", str_error, errno);
- /* Open PIPE */
- fd = open(KEYTONE_PATH, O_WRONLY | O_NONBLOCK);
- if (fd == -1) {
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ /* Write to PIPE */
+ do {
+ written = write(fd, &data, size_to_write);
+ if (written == -1) {
char str_error[256];
+ int errsv = errno;
+
+ strerror_r(errsv, str_error, sizeof(str_error));
+ debug_error("[%d] Fail to write, written = %zd, [%s][%d]",
+ MAX_WRITE_RETRY - retry_remaining, written, str_error, errsv);
- strerror_r(errno, str_error, sizeof(str_error));
- debug_error("Fail to open pipe: [%s][%d]", str_error, errno);
+ if (errsv != EAGAIN || --retry_remaining == 0) {
+ ret = MM_ERROR_SOUND_INTERNAL;
+ break;
+ }
- return MM_ERROR_SOUND_INTERNAL;
+ usleep(WRITE_RETRY_INTERVAL_MS * 1000);
+ } else if (retry_remaining != MAX_WRITE_RETRY) {
+ debug_msg("retry success!!");
}
+ } while (written != size_to_write);
- /* convert volume type to role/volume gain */
- if (role)
- MMSOUND_STRNCPY(data.role, role, ROLE_NAME_LEN);
- if (vol_gain_type)
- MMSOUND_STRNCPY(data.volume_gain_type, vol_gain_type, VOLUME_GAIN_TYPE_LEN);
- MMSOUND_STRNCPY(data.filename, filename, FILE_FULL_PATH);
-
- debug_msg("filepath=[%s], role=[%s], volume_gain_type=[%s]", data.filename, data.role, data.volume_gain_type);
-
- /* Write to PIPE */
- do {
- written = write(fd, &data, size_to_write);
- if (written == -1) {
- char str_error[256];
- int errsv = errno;
-
- strerror_r(errsv, str_error, sizeof(str_error));
- debug_error("[%d] Fail to write, written = %zd, [%s][%d]",
- MAX_WRITE_RETRY - retry_remaining, written, str_error, errsv);
-
- if (errsv != EAGAIN || --retry_remaining == 0) {
- ret = MM_ERROR_SOUND_INTERNAL;
- break;
- }
-
- usleep(WRITE_RETRY_INTERVAL_MS * 1000);
- } else if (retry_remaining != MAX_WRITE_RETRY) {
- debug_msg("retry success!!");
- }
- } while (written != size_to_write);
+ /* Close PIPE */
+ close(fd);
+
+ return ret;
+ }
+
+static int __mm_sound_simple_dbus(const char *filename, int volume_config, const char *method)
+{
+ int ret = MM_ERROR_NONE;
+ const char *role = NULL;
+ const char *vol_gain_type = NULL;
+ GVariant *result = NULL;
+ GDBusConnection *conn = NULL;
+ GError *err = NULL;
+ int idx = 0;
+
+#ifdef USE_LWIPC
+ if (!_mm_sound_check_pa_ready()) {
+ debug_error("Pulseaudio is not ready!");
+ return MM_ERROR_SOUND_INVALID_STATE;
+ }
+#endif
+ if (!method)
+ return MM_ERROR_INVALID_ARGUMENT;
- /* Close PIPE */
- close(fd);
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (!conn || err) {
+ debug_error("g_bus_get_sync() error (%s)", err ? err->message : NULL);
+ g_error_free(err);
+ return MM_ERROR_SOUND_INTERNAL;
+ }
- } else if (ipc_type == IPC_TYPE_DBUS) {
- GVariant *result = NULL;
- GDBusConnection *conn = NULL;
- GError *err = NULL;
- int idx = 0;
+ if (g_strcmp0(method, PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY) == 0) {
+ ret = __verify_input_file(filename);
+ if (ret != MM_ERROR_NONE)
+ goto END;
+
+ role = __convert_volume_type_to_role(AUDIO_VOLUME_CONFIG_TYPE(volume_config));
+ vol_gain_type = __convert_volume_gain_type_to_string(AUDIO_VOLUME_CONFIG_GAIN(volume_config));
+
+ result = g_dbus_connection_call_sync(conn, PA_BUS_NAME,
+ PA_SOUND_PLAYER_OBJECT_PATH,
+ PA_SOUND_PLAYER_INTERFACE,
+ PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY,
+ g_variant_new("(sss)", filename, role, vol_gain_type),
+ NULL, G_DBUS_CALL_FLAGS_NONE, PA_SOUND_RESPONSE_TIMEOUT, NULL, &err);
+ if (!result || err) {
+ debug_error("g_dbus_connection_call_sync() for %s error (%s)", method, err ? err->message : NULL);
+ ret = MM_ERROR_SOUND_INTERNAL;
+ goto END;
+ }
- conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (!conn || err) {
- debug_error("g_bus_get_sync() error (%s)", err ? err->message : NULL);
+ g_variant_get(result, "(i)", &idx);
+ if (idx == -1) {
+ debug_error("[%s] failure, filename(%s)/role(%s)/gain(%s)/stream idx(%d)",
+ method, filename, role, vol_gain_type, idx);
ret = MM_ERROR_SOUND_INTERNAL;
- } else {
- result = g_dbus_connection_call_sync(conn,
- PA_BUS_NAME,
- PA_SOUND_PLAYER_OBJECT_PATH,
- PA_SOUND_PLAYER_INTERFACE,
- PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY,
- g_variant_new("(sss)", filename, role, vol_gain_type),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 2000,
- NULL,
- &err);
- if (!result || err) {
- debug_error("g_dbus_connection_call_sync() for SIMPLE_PLAY error (%s)", err ? err->message : NULL);
- ret = MM_ERROR_SOUND_INTERNAL;
- } else {
- g_variant_get(result, "(i)", &idx);
- if (idx == -1) {
- debug_error("SIMPLE_PLAY failure, filename(%s)/role(%s)/gain(%s)/stream idx(%d)", filename, role, vol_gain_type, idx);
- ret = MM_ERROR_SOUND_INTERNAL;
- } else {
- debug_msg("SIMPLE_PLAY success, filename(%s)/role(%s)/gain(%s)/stream idx(%d)", filename, role, vol_gain_type, idx);
- }
- g_variant_unref(result);
- }
- g_object_unref(conn);
+ goto END;
}
- g_error_free(err);
+ debug_msg("[%s] success, filename(%s)/role(%s)/gain(%s)/stream idx(%d)",
+ method, filename, role, vol_gain_type, idx);
+
+ } else if (g_strcmp0(method, PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP) == 0) {
+ ret = __verify_input_file(filename);
+ if (ret != MM_ERROR_NONE)
+ goto END;
+
+ result = g_dbus_connection_call_sync(conn, PA_BUS_NAME,
+ PA_SOUND_PLAYER_OBJECT_PATH,
+ PA_SOUND_PLAYER_INTERFACE,
+ PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP,
+ g_variant_new("(s)", filename),
+ NULL, G_DBUS_CALL_FLAGS_NONE, PA_SOUND_RESPONSE_TIMEOUT, NULL, &err);
+ if (!result || err) {
+ debug_error("g_dbus_connection_call_sync() for %s error (%s)", method, err ? err->message : NULL);
+ ret = MM_ERROR_SOUND_INTERNAL;
+ goto END;
+ }
+ debug_msg("[%s] done, filename(%s)", method, filename);
+
+ } else if (g_strcmp0(method, PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL) == 0) {
+ result = g_dbus_connection_call_sync(conn, PA_BUS_NAME,
+ PA_SOUND_PLAYER_OBJECT_PATH,
+ PA_SOUND_PLAYER_INTERFACE,
+ PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL,
+ NULL,
+ NULL, G_DBUS_CALL_FLAGS_NONE, PA_SOUND_RESPONSE_TIMEOUT, NULL, &err);
+ if (!result || err) {
+ debug_error("g_dbus_connection_call_sync() for %s error (%s)", method, err ? err->message : NULL);
+ ret = MM_ERROR_SOUND_INTERNAL;
+ goto END;
+ }
+ debug_msg("[%s] done", method);
+
+ } else {
+ debug_error("Invalid Method : %s", method);
+ ret = MM_ERROR_INVALID_ARGUMENT;
}
+END:
+ if (err)
+ g_error_free(err);
+ if (result)
+ g_variant_unref(result);
+ if (conn)
+ g_object_unref(conn);
+
return ret;
-}
+}
\ No newline at end of file