sound-player: support keysound priority 75/303175/1 accepted/tizen_7.0_unified tizen_7.0 accepted/tizen/7.0/unified/20231222.023322 accepted/tizen/7.0/unified/20231222.101429
authorSeungbae Shin <seungbae.shin@samsung.com>
Mon, 20 Nov 2023 10:06:29 +0000 (19:06 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Thu, 21 Dec 2023 02:56:28 +0000 (11:56 +0900)
- The new higher(or the same) priority plays after
  stopping the previous lower(or the same) priority playbacks.
- If the new playback is lower priority, then will be no operation.
- The priority with -1 will be mixed always with others,
  no matter what other playback's priority is.

[Version] 15.0.35
[Issue Type] Feature

Change-Id: I51cf09e08a3bc04c5f0b160c2924a7486d04bade

packaging/pulseaudio-modules-tizen.spec
src/module-sound-player.c

index be642d8ce7eca864de553661cf5aa6230469cc5d..73c495b031f72d5aca535ef97ac33b24b1bce57f 100644 (file)
@@ -2,7 +2,7 @@
 
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          15.0.34
+Version:          15.0.35
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 229501deeccdebd60779b4e7ca8406de648fd23c..edee9071b886bc1e9075da78541c22fd07d829bc 100644 (file)
@@ -94,7 +94,8 @@ enum method_handler_index {
 
 static pa_dbus_arg_info simple_play_args[] = { { "uri", "s", "in" },
                                                { "role", "s", "in" },
-                                               { "volume_gain", "s", "in" } };
+                                               { "volume_gain", "s", "in" },
+                                               { "priority", "i", "in" } };
 static pa_dbus_arg_info simple_stop_args[] = { { "uri", "s", "in" } };
 static pa_dbus_arg_info sample_play_args[] = { { "sample_name", "s", "in" },
                                                { "role", "s", "in" },
@@ -164,6 +165,7 @@ static pa_dbus_interface_info sound_player_interface_info = {
     "   <arg name=\"uri\" direction=\"in\" type=\"s\"/>"                \
     "   <arg name=\"role\" direction=\"in\" type=\"s\"/>"               \
     "   <arg name=\"volume_gain\" direction=\"in\" type=\"s\"/>"        \
+    "   <arg name=\"priority\" direction=\"in\" type=\"i\"/>"           \
     "  </method>"                                                       \
     "  <method name=\"SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP\">"          \
     "   <arg name=\"uri\" direction=\"in\" type=\"s\"/>"                \
@@ -220,11 +222,20 @@ struct userdata {
 
 #define RETRY_NUM 100
 
+#define NO_PRIORITY (-1)
+#define PA_PROP_MEDIA_SIMPLE_PRIORITY "media.simple.priority"
+
+enum priority_result {
+    PRIORITY_BLOCKED,
+    PRIORITY_PASS
+};
+
 struct ipc_data {
     char filename[FILE_FULL_PATH];
     char role[ROLE_NAME_LEN];
     char volume_gain_type[VOLUME_GAIN_TYPE_LEN];
     char method[METHOD_LEN];
+    int priority;
 };
 
 #define KEYTONE_PREFIX      "SIMPLE_PLAY"
@@ -232,7 +243,7 @@ struct ipc_data {
 #define KEYTONE_GROUP       6526            /* Keytone group : assigned by security */
 #define DEFAULT_IPC_TYPE    IPC_TYPE_PIPE
 
-static int _simple_play(struct userdata *u, const char *file_path, const char *role, const char *vol_gain_type) {
+static int _simple_play(struct userdata *u, const char *file_path, const char *role, const char *vol_gain_type, int priority) {
     int ret = 0;
     pa_proplist *p;
 
@@ -247,7 +258,9 @@ static int _simple_play(struct userdata *u, const char *file_path, const char *r
         pa_proplist_sets(p, PA_PROP_MEDIA_ROLE, role);
     if (vol_gain_type)
         pa_proplist_sets(p, PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE, vol_gain_type);
-    pa_log_debug("role[%s], volume_gain_type[%s]", role, vol_gain_type);
+    pa_proplist_setf(p, PA_PROP_MEDIA_SIMPLE_PRIORITY, "%d", priority);
+
+    pa_log_debug("role[%s], volume_gain_type[%s], priority[%d]", role, vol_gain_type, priority);
 
     /* prepare scache */
     scache_name = pa_sprintf_malloc("%s_%s", KEYTONE_PREFIX, file_path);
@@ -406,6 +419,7 @@ static void handle_simple_play(DBusConnection *conn, DBusMessage *msg, void *use
     const char *volume_gain = NULL;
     dbus_int32_t result = -1;
     struct userdata *u = (struct userdata *)userdata;
+    dbus_int32_t priority = NO_PRIORITY;
 
     pa_assert(conn);
     pa_assert(msg);
@@ -415,10 +429,11 @@ static void handle_simple_play(DBusConnection *conn, DBusMessage *msg, void *use
                                        DBUS_TYPE_STRING, &uri,
                                        DBUS_TYPE_STRING, &role,
                                        DBUS_TYPE_STRING, &volume_gain,
+                                       DBUS_TYPE_INT32, &priority,
                                        DBUS_TYPE_INVALID));
-    pa_log_info("uri[%s], role[%s], volume_gain[%s]", uri, role, volume_gain);
+    pa_log_info("uri[%s], role[%s], volume_gain[%s], priority[%d]", uri, role, volume_gain, priority);
     if (uri) {
-        result = _simple_play(u, uri, role, volume_gain);
+        result = _simple_play(u, uri, role, volume_gain, priority);
         if (result != -1) {
             int32_t *stream_idx = pa_xmalloc0(sizeof(int32_t));
             *stream_idx = result;
@@ -742,6 +757,45 @@ static void deinit_ipc(struct userdata *u) {
 #endif
 }
 
+static bool _handle_priority(struct userdata *u, int priority) {
+    pa_sink_input *si = NULL;
+    uint32_t idx = 0;
+    int32_t si_priority = 0;
+    const char *priority_str = NULL;
+
+    pa_assert(u);
+
+    if (priority == NO_PRIORITY)
+        return PRIORITY_PASS;
+
+    PA_IDXSET_FOREACH(si, u->module->core->sink_inputs, idx) {
+        priority_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_SIMPLE_PRIORITY);
+        if (!priority_str) {
+            pa_log_info("sink-input : %u, no priority property", si->index);
+            continue;
+        }
+
+        if (pa_atoi(priority_str, &si_priority) < 0) {
+            pa_log_error("Invalid priority value %s", priority_str);
+            continue;
+        }
+
+        if (si_priority == NO_PRIORITY)
+            continue;
+
+        if (si_priority < priority) {
+            pa_log_info("requested(%d) will be blocked because of existence(%d)", priority, si_priority);
+            return PRIORITY_BLOCKED;
+        }
+
+        pa_log_info("kill sink-input : %u, priority(%d) > requested priority(%d)",
+                   si->index, si_priority, priority);
+        pa_sink_input_kill(si);
+    }
+
+    return PRIORITY_PASS;
+}
+
 static void io_event_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
     struct userdata *u = userdata;
     struct ipc_data data;
@@ -772,17 +826,20 @@ static void io_event_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io
         }
 
         if (read_sum == data_size) {
-            pa_log_info("name(%s), role(%s), volume_gain_type(%s), method(%s)",
-                    data.filename, data.role, data.volume_gain_type, data.method);
-
-            if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY, METHOD_LEN))
-                _simple_play(u, data.filename, data.role, data.volume_gain_type);
-            else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP, METHOD_LEN))
+            pa_log_info("name(%s), role(%s), volume_gain_type(%s), priority(%d), method(%s)",
+                    data.filename, data.role, data.volume_gain_type, data.priority, data.method);
+
+            if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY, METHOD_LEN)) {
+                if (_handle_priority(u, data.priority) == PRIORITY_BLOCKED)
+                    return;
+                _simple_play(u, data.filename, data.role, data.volume_gain_type, data.priority);
+            } else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP, METHOD_LEN)) {
                 _simple_stop(u, data.filename);
-            else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL, METHOD_LEN))
+            } else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL, METHOD_LEN)) {
                 _simple_stop_all(u);
-            else
+            } else {
                 pa_log_error("Invalid method!!!");
+            }
         } else {
             pa_log_warn("Fail to read, retry_count(%d), read sum(%zu), err(%s)", retry_count, read_sum, pa_cstrerror(errno));
         }