sound-player: support keysound priority 96/301596/6
authorSeungbae Shin <seungbae.shin@samsung.com>
Mon, 20 Nov 2023 10:06:29 +0000 (19:06 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Mon, 18 Dec 2023 07:14:37 +0000 (16:14 +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.70
[Issue Type] Feature

Change-Id: I51cf09e08a3bc04c5f0b160c2924a7486d04bade

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

index 8736ad12ce8aba695b6c3edbb2de843a8c1c6e75..011e84efb85a32d8c4ee8d0192424564970c3234 100644 (file)
@@ -2,7 +2,7 @@
 
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          15.0.69
+Version:          15.0.70
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 5773c47b03824196f33600aea41c99c957109443..65f77962b612928026389a24c56257e55bcd2c57 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" },
@@ -165,6 +166,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\"/>"                \
@@ -222,11 +224,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"
@@ -234,7 +245,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;
 
@@ -249,7 +260,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);
@@ -408,6 +421,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);
@@ -417,10 +431,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;
@@ -749,6 +764,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;
@@ -779,17 +833,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));
         }