Add mm_sound_stop_keysound() 21/227321/7 accepted/tizen/unified/20200323.172912 submit/tizen/20200323.095035
authorSeungbae Shin <seungbae.shin@samsung.com>
Wed, 11 Mar 2020 07:32:48 +0000 (16:32 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Mon, 23 Mar 2020 03:41:00 +0000 (12:41 +0900)
[Version] 0.12.66
[Issue Type] Add

Change-Id: I2e17159bcafabc4056fcae7cff62ec1a70403c95

include/mm_sound_private.h
mm_sound_keysound.c
packaging/libmm-sound.spec
testsuite/mm_sound_testsuite_simple.c

index de2deac..9258ce7 100644 (file)
@@ -59,17 +59,30 @@ typedef struct {
  * This function is to play key sound.
  *
  * @param      filename                [in] keytone filename to play
- * @param      volume_config   [in] Volume type & volume gain
+ * @param      volume_config   [in] volume type & volume gain
  *
  * @return     This function returns MM_ERROR_NONE on success, or negative value
  *                     with error code.
  *
  * @remark     This function provide low latency sound play (such as dialer keytone)
  *                     using fixed spec of wave file (44100Hz, mono channel)
- * @see                volume_type_t volume_gain_t mm_sound_volume_set_value
+ * @see                mm_sound_stop_keysound()
+ * @see                volume_type_t volume_gain_t
  */
 int mm_sound_play_keysound(const char *filename, int volume_config);
 
+/**
+ * This function is to stop key sound.
+ *
+ * @param      filename                [in] keytone filename to stop (can be null if whole exist keytones need stops)
+ *
+ * @return     This function returns MM_ERROR_NONE on success, or negative value
+ *                     with error code.
+ *
+ * @see                mm_sound_play_keysound()
+ */
+int mm_sound_stop_keysound(const char *filename);
+
 int mm_sound_boot_ready(int timeout_sec);
 
 int mm_sound_boot_play_sound(char* path);
index 3c6c95c..38f4a0b 100644 (file)
 #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) {
@@ -89,7 +90,7 @@ static const char* convert_volume_type_to_role(int 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) {
@@ -123,7 +124,14 @@ static const char* convert_volume_gain_type_to_string(int 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
@@ -145,12 +153,32 @@ static bool _mm_sound_check_pa_ready()
 }
 #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()) {
@@ -159,114 +187,171 @@ static int _mm_sound_play_keysound(const char *filename, int volume_config, ipc_
        }
 #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
index 9c5a536..f1cdb55 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-sound
 Summary:    MMSound Package contains client lib and sound_server binary
-Version:    0.12.65
+Version:    0.12.66
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
index f72e2fd..677c9ff 100755 (executable)
@@ -44,8 +44,9 @@
 #include <dirent.h>
 #include <vconf.h>
 
-#define POWERON_FILE   "/usr/share/feedback/sound/operation/power_on.wav"
-#define KEYTONE_FILE   "/usr/share/feedback/sound/operation/operation.wav"
+#define POWERON_FILE   "/usr/share/keysound/poweron.ogg"
+#define KEYTONE_FILE   "/usr/share/sounds/sound-server/Tizen_HW_Touch.ogg"
+#define KEYTONE_NOTI_FILE      "/usr/share/sounds/alsa/Front_Center.wav"
 
 enum {
        CURRENT_STATUS_MAINMENU = 0,
@@ -195,7 +196,11 @@ static void displaymenu()
                g_print("==================================================================\n");
                g_print("       Sound Play APIs\n");
                g_print("==================================================================\n");
-               g_print("k : Key Sound     \t");
+               g_print("k : Play Keysound     \t");
+               g_print("ks : Stop Keysound     \t");
+               g_print("kn : Play Keysound (Notification) \t");
+               g_print("ksn : Stop Keysound (Notification)    \t");
+               g_print("ksa : Stop Keysound (All)    \n");
                g_print("as : play sound with stream type\n");
                g_print("FS : Play DTMF with stream type\t");
                g_print("b : Play directory\n");
@@ -498,10 +503,26 @@ static void interpret(char *cmd)
                        ret = mm_sound_unset_focus_watch_callback(g_focus_watch_index);
                        if (ret)
                                g_print("failed to mm_sound_unset_focus_watch_callback(), ret[0x%x]\n", ret);
+               } else if (strncmp(cmd, "ksn", 3) == 0) {
+                       ret = mm_sound_stop_keysound(KEYTONE_NOTI_FILE);
+                       if (ret < 0)
+                               debug_error("keysound stop(noti) failed with 0x%x", ret);
+               } else if (strncmp(cmd, "ksa", 3) == 0) {
+                       ret = mm_sound_stop_keysound(NULL);
+                       if (ret < 0)
+                               debug_error("keysound stop(all) failed with 0x%x", ret);
+               } else if (strncmp(cmd, "kn", 2) == 0) {
+                       ret = mm_sound_play_keysound(KEYTONE_NOTI_FILE, VOLUME_TYPE_NOTIFICATION);
+                       if (ret < 0)
+                               debug_error("keysound play(noti) failed with 0x%x", ret);
+               } else if (strncmp(cmd, "ks", 2) == 0) {
+                       ret = mm_sound_stop_keysound(KEYTONE_FILE);
+                       if (ret < 0)
+                               debug_error("keysound stop failed with 0x%x", ret);
                } else if (strncmp(cmd, "k", 1) == 0) {
                        ret = mm_sound_play_keysound(KEYTONE_FILE, 0);
                        if (ret < 0)
-                               debug_log("keysound play failed with 0x%x", ret);
+                               debug_error("keysound play failed with 0x%x", ret);
                } else if (strcmp(cmd, "dbus-m") == 0) {
                        int ret = 0;
                        int a = 3;