stream-manager: Add Dbus interface for getting current media routing path 20/103420/5
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 8 Dec 2016 08:04:26 +0000 (17:04 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 8 Dec 2016 08:48:24 +0000 (17:48 +0900)
server          : org.pulseaudio.Server
object path     : /org/pulseaudio/StreamManager
interface       : org.pulseaudio.StreamManager
method name     : GetCurrentMediaRoutingPath
method argument : #1 string for direction ("in" or "out")
return value    : #1 string for device type
                  #2 string for error message

[Version] 5.0.101
[Profile] Common
[Issue Type] Feature enhancement

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

index 56e5768..cdacead 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          5.0.100
+Version:          5.0.101
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 1dfc829..34e298a 100644 (file)
 #define STREAM_MANAGER_OBJECT_PATH "/org/pulseaudio/StreamManager"
 #define STREAM_MANAGER_INTERFACE   "org.pulseaudio.StreamManager"
 /* method */
-#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO            "GetStreamInfo"
-#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST            "GetStreamList"
-#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES   "SetStreamRouteDevices"
-#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION    "SetStreamRouteOption"
-#define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL           "SetVolumeLevel"
-#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL           "GetVolumeLevel"
-#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_UPDATE_FOCUS_STATUS        "UpdateFocusStatus"
-#define STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION         "UpdateRestriction"
+#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO                   "GetStreamInfo"
+#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST                   "GetStreamList"
+#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES          "SetStreamRouteDevices"
+#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION           "SetStreamRouteOption"
+#define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL                  "SetVolumeLevel"
+#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL                  "GetVolumeLevel"
+#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_MEDIA_ROUTING_PATH    "GetCurrentMediaRoutingPath"
+#define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS               "UpdateFocusStatus"
+#define STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION                "UpdateRestriction"
 /* signal */
-#define STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED             "VolumeChanged"
-#define STREAM_MANAGER_SIGNAL_NAME_COMMAND                    "Command"
+#define STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED                    "VolumeChanged"
+#define STREAM_MANAGER_SIGNAL_NAME_COMMAND                           "Command"
+
+#define IS_AVAILABLE_DIRECTION(stream_type, device_direction) \
+    ((stream_type == STREAM_SINK_INPUT) ? (device_direction & DM_DEVICE_DIRECTION_OUT) : (device_direction & DM_DEVICE_DIRECTION_IN))
 
 static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m, void *userdata);
 static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -80,6 +84,7 @@ static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg,
 static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_update_restriction(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);
@@ -96,6 +101,7 @@ enum method_handler_index {
     METHOD_HANDLER_SET_VOLUME_MUTE,
     METHOD_HANDLER_GET_VOLUME_MUTE,
     METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE,
+    METHOD_HANDLER_GET_CURRENT_MEDIA_ROUTING_PATH,
     METHOD_HANDLER_UPDATE_FOCUS_STATUS,
     METHOD_HANDLER_UPDATE_RESTRICTION,
     METHOD_HANDLER_MAX
@@ -141,13 +147,16 @@ static pa_dbus_arg_info get_volume_mute_args[]  = { { "io_direction", "s", "in"
 static pa_dbus_arg_info get_current_volume_type_args[]  = { { "io_direction", "s", "in" },
                                                                    { "type", "s", "out" },
                                                               { "ret_msg", "s", "out" } };
+static pa_dbus_arg_info get_current_media_routing_path_args[]  = { { "io_direction", "s", "in" },
+                                                                   { "device_type", "s", "out" },
+                                                                     { "ret_msg", "s", "out" } };
 static pa_dbus_arg_info update_focus_status_args[]  = { { "parent_id", "u", "in" },
                                                      { "focus_status", "u", "in" },
                                                        { "ret_msg", "s", "out" } };
 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", "uu", "su"};
+static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "s", "uu", "su"};
 
 static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
     [METHOD_HANDLER_GET_STREAM_INFO] = {
@@ -200,6 +209,11 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
         .arguments = get_current_volume_type_args,
         .n_arguments = sizeof(get_current_volume_type_args) / sizeof(pa_dbus_arg_info),
         .receive_cb = handle_get_current_volume_type },
+    [METHOD_HANDLER_GET_CURRENT_MEDIA_ROUTING_PATH] = {
+        .method_name = STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH,
+        .arguments = get_current_media_routing_path_args,
+        .n_arguments = sizeof(get_current_media_routing_path_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_current_media_routing_path },
     [METHOD_HANDLER_UPDATE_FOCUS_STATUS] = {
         .method_name = STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS,
         .arguments = update_focus_status_args,
@@ -299,6 +313,11 @@ static pa_dbus_interface_info stream_manager_interface_info = {
     "   <arg name=\"type\" direction=\"out\" type=\"s\"/>"                   \
     "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
     "  </method>"                                                            \
+    "  <method name=\"STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH\">" \
+    "   <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>"                   \
+    "   <arg name=\"device_type\" direction=\"out\" type=\"s\"/>"                   \
+    "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                       \
+    "  </method>"                                                                   \
     "  <method name=\"STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS\">"     \
     "   <arg name=\"parent_id\" direction=\"in\" type=\"u\"/>"               \
     "   <arg name=\"focus_status\" direction=\"in\" type=\"u\"/>"            \
@@ -1085,6 +1104,95 @@ fail:
     dbus_message_unref(reply);
 }
 
+static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    const char *direction = NULL;
+    const char *device_type = NULL;
+    const char *dm_device_type = NULL;
+    dm_device_direction_t dm_device_direction = DM_DEVICE_DIRECTION_NONE;
+    stream_info *s = NULL;
+    stream_type_t stream_type = STREAM_SINK_INPUT;
+    DBusMessage *reply = NULL;
+    uint32_t idx = 0;
+    uint32_t conn_idx = 0;
+    pa_idxset *conn_devices = NULL;
+    pa_tz_device *device = NULL;
+    pa_tz_device *latest_device = NULL;
+    pa_stream_manager *m = (pa_stream_manager*)userdata;
+    pa_usec_t creation_time = 0;
+    pa_usec_t latest_creation_time = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_STRING, &direction,
+                                       DBUS_TYPE_INVALID));
+    pa_log_info("handle_get_current_media_routing_path(), direction[%s]", 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_log_error("invalid stream type[%s]", direction);
+        goto fail;
+    }
+
+    if ((s = pa_hashmap_get(m->stream_infos, STREAM_ROLE_MEDIA))) {
+        /* get current connected devices */
+        conn_devices = pa_device_manager_get_device_list(m->dm);
+
+        if (s->route_type == STREAM_ROUTE_TYPE_AUTO) {
+            PA_IDXSET_FOREACH(device_type, (stream_type == STREAM_SINK_INPUT) ? s->idx_avail_out_devices : s->idx_avail_in_devices, idx) {
+                PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
+                    dm_device_type = pa_tz_device_get_type(device);
+                    dm_device_direction = pa_tz_device_get_direction(device);
+                    if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(stream_type, dm_device_direction))
+                        goto success;
+                }
+            }
+            pa_log_error("could not found matched device");
+        } else if (s->route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
+            PA_IDXSET_FOREACH(device_type, (stream_type == STREAM_SINK_INPUT) ? s->idx_avail_out_devices : s->idx_avail_in_devices, idx) {
+                PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
+                    dm_device_type = pa_tz_device_get_type(device);
+                    dm_device_direction = pa_tz_device_get_direction(device);
+                    creation_time = pa_tz_device_get_creation_time(device);
+                    if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(stream_type, dm_device_direction)) {
+                        if (!latest_device || (latest_creation_time <= creation_time)) {
+                            latest_device = device;
+                            latest_creation_time = creation_time;
+                        }
+                    }
+                }
+            }
+            if (latest_device) {
+                device_type = pa_tz_device_get_type(latest_device);
+                goto success;
+            }
+            pa_log_error("could not found matched device");
+        } else
+          pa_log_error("unexpected routing type for media[%d]", s->route_type);
+
+    } else
+        pa_log_error("could not find media role");
+
+fail:
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &dbus_str_none, DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+    return;
+success:
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &device_type, DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
 static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     uint32_t id = 0;
     uint32_t idx = 0;
index 4779fc7..e2865c0 100644 (file)
@@ -39,6 +39,7 @@
 #define GET_STREAM_PROPLIST(stream, type) \
       (type == STREAM_SINK_INPUT ? ((pa_sink_input*)stream)->proplist : ((pa_source_output*)stream)->proplist)
 
+#define STREAM_ROLE_MEDIA               "media"
 #define STREAM_ROLE_RINGTONE_CALL       "ringtone-call"
 #define STREAM_ROLE_CALL_VOICE          "call-voice"
 #define STREAM_ROLE_CALL_VIDEO          "call-video"