stream-manager: Add new DBus method to check if there is a running stream created... 57/126057/3
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 20 Apr 2017 01:44:13 +0000 (10:44 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 21 Apr 2017 00:40:39 +0000 (09:40 +0900)
  server          : org.pulseaudio.Server
  object path     : /org/pulseaudio/StreamManager
  interface       : org.pulseaudio.StreamManager
  method name     : CheckStreamExistByPid
  method argument : #1 uint32 for process id
                    #2 string for stream_type
                    #3 string for direction ("in" or "out")
  return value    : string for return message
                      - existace     : "STREAM_MANAGER_RETURN_OK"
                      - no existance : "STREAM_MANAGER_RETURN_ERROR_NO_STREAM"
                      - error        : "STREAM_MANAGER_RETURN_ERROR"

[Version] 5.0.143
[Profile] Common
[Issue Type] New API

Change-Id: Ia0c5b8bfcc9476c36880420f6a4244ac7dce22b0
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/stream-manager.c

index ac5fc7dfa48906d09ffe3e2d0814fd2925aac7ce..5fe479e5c634783591267777696e2c98fcf58371 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          5.0.142
+Version:          5.0.143
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index de28fc9016cd45d0698cf4b3745016e9ac9caf1c..18c4b01f88c5c6838e5a72af792f3ae4cb01db13 100644 (file)
 #define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL              "GetVolumeMaxLevel"
 #define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_MUTE                   "SetVolumeMute"
 #define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MUTE                   "GetVolumeMute"
-#define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE           "GetCurrentVolumeType" /* the type that belongs to the stream of the current max priority */
+#define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE           "GetCurrentVolumeType" /* The type that belongs to the stream of the current max priority */
 #define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH    "GetCurrentMediaRoutingPath"
 #define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS               "UpdateFocusStatus"
 #define STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION                "UpdateRestriction"
 #define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS_BY_FOCUS_ID   "UpdateFocusStatusByFocusId" /* Similar to UpdateFocusStatus but using focus id, it is only for backward compatibility */
+#define STREAM_MANAGER_METHOD_NAME_CHECK_STREAM_EXIST_BY_PID         "CheckStreamExistByPid"
 /* signal */
 #define STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED                    "VolumeChanged"
 #define STREAM_MANAGER_SIGNAL_NAME_COMMAND                           "Command"
@@ -94,6 +95,7 @@ static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMess
 static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_update_focus_status_by_focus_id(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_check_stream_exist_by_pid(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void send_volume_changed_signal(DBusConnection *conn, const char *direction, const char *volume_type, const uint32_t volume_level);
 static void send_command_signal(DBusConnection *conn, const char *name, int value);
 
@@ -112,6 +114,7 @@ enum method_handler_index {
     METHOD_HANDLER_UPDATE_FOCUS_STATUS,
     METHOD_HANDLER_UPDATE_FOCUS_STATUS_BY_FOCUS_ID,
     METHOD_HANDLER_UPDATE_RESTRICTION,
+    METHOD_HANDLER_CHECK_STREAM_EXIST_BY_PID,
     METHOD_HANDLER_MAX
 };
 
@@ -167,7 +170,11 @@ static pa_dbus_arg_info update_focus_status_by_focus_id_args[]  = { { "focus_id"
 static pa_dbus_arg_info update_restriction_args[]  = { { "name", "s", "in" },
                                                       { "value", "u", "in" },
                                                  { "ret_msg", "s", "out" } };
-static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "s", "uu", "iu", "su"};
+static pa_dbus_arg_info check_stream_exist_by_pid_args[]  = { { "pid", "u", "in" },
+                                                      { "stream_type", "s", "in" },
+                                                     { "io_direction", "s", "in" },
+                                                       { "ret_msg", "s", "out" } };
+static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "s", "uu", "iu", "su", "uss"};
 
 static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
     [METHOD_HANDLER_GET_STREAM_INFO] = {
@@ -240,6 +247,11 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
         .arguments = update_restriction_args,
         .n_arguments = sizeof(update_restriction_args) / sizeof(pa_dbus_arg_info),
         .receive_cb = handle_update_restriction },
+    [METHOD_HANDLER_CHECK_STREAM_EXIST_BY_PID] = {
+        .method_name = STREAM_MANAGER_METHOD_NAME_CHECK_STREAM_EXIST_BY_PID,
+        .arguments = check_stream_exist_by_pid_args,
+        .n_arguments = sizeof(check_stream_exist_by_pid_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_check_stream_exist_by_pid },
 };
 
 const char *dbus_str_none = "none";
@@ -349,6 +361,12 @@ static pa_dbus_interface_info stream_manager_interface_info = {
     "   <arg name=\"value\" direction=\"in\" type=\"u\"/>"                   \
     "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
     "  </method>"                                                            \
+    "  <method name=\"STREAM_MANAGER_METHOD_NAME_CHECK_STREAM_EXIST_BY_PID\">" \
+    "   <arg name=\"pid\" direction=\"in\" type=\"u\"/>"                       \
+    "   <arg name=\"stream_type\" direction=\"in\" type=\"s\"/>"               \
+    "   <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>"              \
+    "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                  \
+    "  </method>"                                                              \
     "  <signal name=\"STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED\">"          \
     "   <arg name=\"direction\" type=\"s\"/>"                                \
     "   <arg name=\"volume_type\" type=\"s\"/>"                              \
@@ -1008,6 +1026,40 @@ static void set_initial_active_device(pa_stream_manager *m) {
     set_media_active_device(m);
 }
 
+static bool check_stream_exist_by_pid(pa_stream_manager *m, uint32_t pid, const char *stream_role, stream_type_t type) {
+    void *stream = NULL;
+    uint32_t idx = 0;
+    const char *role = NULL;
+    const char *app_pid_str = NULL;
+    uint32_t app_pid = 0;
+
+    pa_assert(m);
+    pa_assert(stream_role);
+
+    pa_log_info("check_stream_exist_by_pid(), pid[%u], role[%s], type[%d]", pid, stream_role, type);
+
+    PA_IDXSET_FOREACH(stream, (type == STREAM_SINK_INPUT) ? m->core->sink_inputs : m->core->source_outputs, idx) {
+        role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE);
+        if (!pa_safe_streq(role, stream_role))
+            continue;
+
+        if (!CHECK_STREAM_RUNNING(stream, type)) {
+            pa_log_info("stream(%p, index:%u) is not in running state, skip it.", stream, GET_STREAM_INDEX(stream, type));
+            continue;
+        }
+
+        app_pid_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_APPLICATION_PROCESS_ID);
+        if (app_pid_str && !pa_atou(app_pid_str, &app_pid)) {
+            if (app_pid == pid) {
+                pa_log_info("found matching stream(%p, index:%u)", stream, GET_STREAM_INDEX(stream, type));
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
 static void update_devices_and_trigger_routing(pa_stream_manager *m, stream_parent *sp, stream_type_t type) {
     void *stream = NULL;
     pa_idxset *idx_streams = NULL;
@@ -1690,6 +1742,50 @@ fail:
     dbus_message_unref(reply);
 }
 
+static void handle_check_stream_exist_by_pid(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    uint32_t pid = 0;
+    const char *type;
+    const char *direction;
+    stream_type_t stream_type = STREAM_SINK_INPUT;
+    DBusMessage *reply = NULL;
+    pa_stream_manager *m = (pa_stream_manager*)userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_UINT32, &pid,
+                                       DBUS_TYPE_STRING, &type,
+                                       DBUS_TYPE_STRING, &direction,
+                                       DBUS_TYPE_INVALID));
+    pa_log_info("handle_check_stream_exist_by_pid(), pid[%u], type[%s], direction[%s]", pid, type, direction);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    if (pa_streq(direction, "in"))
+        stream_type = STREAM_SOURCE_OUTPUT;
+    else if (pa_streq(direction, "out"))
+        stream_type = STREAM_SINK_INPUT;
+    else {
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR],
+                     DBUS_TYPE_INVALID));
+        goto fail;
+    }
+
+    if (!check_stream_exist_by_pid(m, pid, type, stream_type)) {
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR_NO_STREAM],
+                     DBUS_TYPE_INVALID));
+        goto fail;
+    }
+
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK],
+                 DBUS_TYPE_INVALID));
+fail:
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
 static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     int idx = 0;
     pa_stream_manager *m = (pa_stream_manager*)userdata;