stream is on device 53/104553/1
authorJeongho Mok <jho.mok@samsung.com>
Mon, 12 Dec 2016 02:28:06 +0000 (11:28 +0900)
committerJeongho Mok <jho.mok@samsung.com>
Tue, 13 Dec 2016 13:18:11 +0000 (05:18 -0800)
[Version] 5.0.104
[Profile] Common
[Issue Type] Enhancement

Change-Id: Ie71658e66b441d59b72e2079f38322ae8af9109b
(cherry picked from commit 876756bb03a3950c9314cce0c8cb32ae81677088)

packaging/pulseaudio-modules-tizen.spec
src/device-manager.c
src/tizen-device.c
src/tizen-device.h

index bf45b4b..ffe3da4 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          5.0.103
+Version:          5.0.104
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index daba72e..1691005 100644 (file)
     "   <arg name=\"mask_flags\" direction=\"in\" type=\"i\"/>\n"                           \
     "   <arg name=\"ConnectedDeviceList\" direction=\"out\" type=\"a(isiis)\"/>\n"          \
     "  </method>\n"                                                                         \
+    "  <method name=\"IsStreamOnDevice\">\n"                                          \
+    "   <arg name=\"stream_id\" direction=\"in\" type=\"i\"/>\n"                           \
+    "   <arg name=\"device_id\" direction=\"in\" type=\"i\"/>\n"          \
+    "   <arg name=\"is_on\" direction=\"out\" type=\"b\"/>\n"          \
+    "  </method>\n"                                                                         \
     "  <method name='GetBTA2DPStatus'>"                                                     \
     "    <arg type='b' name='is_bt_on' direction='out'/>"                                   \
     "    <arg type='s' name='bt_name' direction='out'/>"                                    \
@@ -387,6 +392,7 @@ struct composite_type {
 /*** Defines for method handle ***/
 /* method handlers */
 static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -395,6 +401,7 @@ static int method_call_bt_get_name(DBusConnection *conn, const char *device_path
 
 enum method_handler_index {
     METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST,
+    METHOD_HANDLER_IS_STREAM_ON_DEVICE,
     METHOD_HANDLER_GET_BT_A2DP_STATUS,
     METHOD_HANDLER_LOAD_SINK,
     METHOD_HANDLER_STATUS_TEST,
@@ -405,6 +412,9 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
     [METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST] = {
         .method_name = "GetConnectedDeviceList",
         .receive_cb = handle_get_connected_device_list },
+    [METHOD_HANDLER_IS_STREAM_ON_DEVICE] = {
+        .method_name = "IsStreamOnDevice",
+        .receive_cb = handle_is_stream_on_device},
     [METHOD_HANDLER_GET_BT_A2DP_STATUS] = {
         .method_name = "GetBTA2DPStatus",
         .receive_cb = handle_get_bt_a2dp_status },
@@ -2455,38 +2465,62 @@ static void unwatch_signals(pa_device_manager *dm) {
     dbus_connection_remove_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm);
 }
 
-static void send_device_connection_changed_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) {
-    DBusMessage *signal_msg;
-    DBusMessageIter msg_iter, device_iter;
-    dbus_bool_t _connected = connected;
-    dm_device_state_t compound_state;
-    dbus_int32_t device_id, direction;
+static void fill_signal_msg_with_device(const char *description, DBusMessageIter *msg_iter, uint32_t event_id, pa_tz_device *device) {
+    DBusMessageIter array_iter, device_iter;
     char *type, *name;
+    dbus_int32_t device_id, direction, state, stream_id;
+    pa_intset *stream_id_set = NULL;
+    int32_t stream_id_val;
+    int ret;
 
+    pa_assert(msg_iter);
     pa_assert(device);
-    pa_assert(dm);
 
-    pa_log_info("Send device connection changed signal, event_id(%u)", event_id);
-
-    pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected"));
-    dbus_message_iter_init_append(signal_msg, &msg_iter);
-    dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_UINT32, &event_id);
-    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter));
+    dbus_message_iter_append_basic(msg_iter, DBUS_TYPE_UINT32, &event_id);
+    pa_assert_se(dbus_message_iter_open_container(msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter));
 
     direction = (dbus_int32_t) pa_tz_device_get_direction(device);
     type = pa_tz_device_get_type(device);
     name = pa_tz_device_get_name(device);
     device_id = (dbus_int32_t) pa_tz_device_get_id(device);
-    compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
+    state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
 
-    simple_device_dump(PA_LOG_INFO, connected ? "[Connected]" : "[Disconnected]", device_id, type, name, direction, compound_state);
+    simple_device_dump(PA_LOG_INFO, description, device_id, type, name, direction, state);
 
     dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id);
     dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type);
     dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state);
+    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &state);
     dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name);
-    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter));
+    if (state == DM_DEVICE_STATE_ACTIVATED)
+        stream_id_set = pa_tz_device_get_stream_list(device);
+    pa_assert_se(dbus_message_iter_open_container(&device_iter, DBUS_TYPE_ARRAY, "i", &array_iter));
+    if (state == DM_DEVICE_STATE_ACTIVATED) {
+        PA_INTSET_FOREACH(stream_id_val, stream_id_set, ret) {
+            stream_id = stream_id_val;
+            dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_INT32, &stream_id);
+        }
+    }
+    pa_assert_se(dbus_message_iter_close_container(&device_iter, &array_iter));
+    if (stream_id_set)
+        pa_intset_free(stream_id_set);
+    pa_assert_se(dbus_message_iter_close_container(msg_iter, &device_iter));
+}
+
+static void send_device_connection_changed_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) {
+    DBusMessage *signal_msg;
+    DBusMessageIter msg_iter;
+    dbus_bool_t _connected = connected;
+
+    pa_assert(device);
+    pa_assert(dm);
+
+    pa_log_info("Send device connection changed signal, event_id(%u)", event_id);
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected"));
+    dbus_message_iter_init_append(signal_msg, &msg_iter);
+    fill_signal_msg_with_device(connected ? "[Connected]" : "[Disconnected]", &msg_iter, event_id, device);
+
     dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected);
 
     pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL));
@@ -2496,10 +2530,7 @@ static void send_device_connection_changed_signal(uint32_t event_id, pa_tz_devic
 
 static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *device, int changed_type, pa_device_manager *dm) {
     DBusMessage *signal_msg;
-    DBusMessageIter msg_iter, device_iter;
-    dm_device_state_t compound_state;
-    dbus_int32_t device_id, direction;
-    char *type, *name;
+    DBusMessageIter msg_iter;
     const char *changed_prefix[] = {"[State Changed]", "[Direction Changed]", "[Avail-Mode Changed]"};
 
     pa_assert(device);
@@ -2509,23 +2540,7 @@ static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *dev
 
     pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceInfoChanged"));
     dbus_message_iter_init_append(signal_msg, &msg_iter);
-    dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_UINT32, &event_id);
-    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter));
-
-    direction = (dbus_int32_t) pa_tz_device_get_direction(device);
-    type = pa_tz_device_get_type(device);
-    name = pa_tz_device_get_name(device);
-    device_id = (dbus_int32_t) pa_tz_device_get_id(device);
-    compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
-
-    simple_device_dump(PA_LOG_DEBUG, changed_prefix[changed_type], device_id, type, name, direction, compound_state);
-
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name);
-    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter));
+    fill_signal_msg_with_device(changed_prefix[changed_type], &msg_iter, event_id, device);
     dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &changed_type);
 
     pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL));
@@ -2535,10 +2550,7 @@ static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *dev
 
 static void send_device_state_changed_signal(uint32_t event_id, pa_tz_device *device, bool activated, pa_device_manager *dm) {
     DBusMessage *signal_msg;
-    DBusMessageIter msg_iter, device_iter;
-    dm_device_state_t compound_state;
-    dbus_int32_t device_id, direction;
-    char *type, *name;
+    DBusMessageIter msg_iter;
 
     pa_assert(device);
     pa_assert(dm);
@@ -2547,23 +2559,7 @@ static void send_device_state_changed_signal(uint32_t event_id, pa_tz_device *de
 
     pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceStateChanged"));
     dbus_message_iter_init_append(signal_msg, &msg_iter);
-    dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_UINT32, &event_id);
-    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter));
-
-    direction = (dbus_int32_t) pa_tz_device_get_direction(device);
-    type = pa_tz_device_get_type(device);
-    name = pa_tz_device_get_name(device);
-    device_id = (dbus_int32_t) pa_tz_device_get_id(device);
-    compound_state = activated ? DM_DEVICE_STATE_ACTIVATED : DM_DEVICE_STATE_DEACTIVATED;
-
-    simple_device_dump(PA_LOG_DEBUG, "[State Changed]", device_id, type, name, direction, compound_state);
-
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state);
-    dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name);
-    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter));
+    fill_signal_msg_with_device(activated ? "[Activated]" : "[Deactivated]", &msg_iter, event_id, device);
 
     pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL));
 
@@ -2734,6 +2730,58 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *
     dbus_message_unref(reply);
 }
 
+static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_device_manager *manager;
+    DBusMessage *reply;
+    pa_tz_device *device;
+    dbus_bool_t is_on = false;
+    dbus_int32_t stream_id, device_id;
+    pa_intset *stream_id_set;
+    int32_t stream_id_val;
+    int ret;
+    dm_device_state_t state;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(userdata);
+
+    pa_log_info("Is stream on device");
+
+    manager = (pa_device_manager*) userdata;
+
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_INT32, &stream_id,
+                                       DBUS_TYPE_INT32, &device_id,
+                                       DBUS_TYPE_INVALID));
+
+    if ((device = _device_list_get_device_with_id(manager, device_id))) {
+        pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+        state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
+        if (state == DM_DEVICE_STATE_ACTIVATED) {
+            stream_id_set = pa_tz_device_get_stream_list(device);
+            PA_INTSET_FOREACH(stream_id_val, stream_id_set, ret) {
+                if (stream_id_val == stream_id) {
+                    is_on = true;
+                    pa_log_info("stream(%d) is on device(%d)", stream_id, device_id);
+                    break;
+                }
+            }
+        } else {
+            pa_log_info("device(%d) is not activated, regard as no stream on it", device_id);
+            is_on = false;
+        }
+
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_on,
+                                                     DBUS_TYPE_INVALID));
+
+        pa_assert_se(dbus_connection_send(conn, reply, NULL));
+        dbus_message_unref(reply);
+    } else {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.Internal");
+    }
+}
 
 static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_device_manager *dm;
index 67eae6d..9279bc4 100644 (file)
 
 #define COMPOUND_STATE(d) (((pa_tz_device*)d)->playback_state | ((pa_tz_device*)d)->capture_state)
 
+struct pa_intset {
+    int values[MAX_INTSET_NUM];
+    uint32_t write_index;
+    uint32_t read_index;
+};
+
 int device_id_max_g = 1;
 uint32_t event_id_max_g = 1;
 
@@ -28,6 +34,64 @@ static uint32_t _new_event_id() {
     return event_id_max_g++;
 }
 
+int pa_intset_put(pa_intset *s, int val) {
+    int i;
+
+    pa_assert(s);
+
+    if (s->write_index >= MAX_INTSET_NUM)
+        return -1;
+
+    for(i = 0; i < s->write_index; i++) {
+        if (s->values[i] == val)
+            return -1;
+    }
+
+    s->values[s->write_index++] = val;
+
+    return 0;
+}
+
+pa_intset* pa_intset_new() {
+    pa_intset *s;
+
+    s = pa_xmalloc0(sizeof(pa_intset));
+    s->write_index = 0;
+    s->read_index = 0;
+
+    return s;
+}
+
+void pa_intset_free(pa_intset *s) {
+    pa_assert(s);
+    pa_xfree(s);
+}
+
+int pa_intset_first(pa_intset *s, int *val) {
+    pa_assert(s);
+    pa_assert(val);
+
+    if (s->write_index == 0)
+        return -1;
+
+    s->read_index = 0;
+    *val = s->values[s->read_index++];
+
+    return 0;
+}
+
+int pa_intset_next(pa_intset *s, int *val) {
+    pa_assert(s);
+    pa_assert(val);
+
+    if (s->read_index >= s->write_index)
+        return -1;
+
+    *val = s->values[s->read_index++];
+
+    return 0;
+}
+
 static char* get_playback_list_str(pa_hashmap *playback_devices) {
     pa_sink *sink = NULL;
     void *state;
@@ -593,6 +657,44 @@ bool pa_tz_device_is_all_suspended(pa_tz_device *device) {
     return true;
 }
 
+pa_intset* pa_tz_device_get_stream_list(pa_tz_device *device) {
+    pa_sink *sink;
+    pa_source *source;
+    pa_sink_input *input;
+    pa_source_output *output;
+    void *state;
+    const char *p_id_str;
+    int32_t p_id;
+    uint32_t idx;
+    pa_intset *stream_id_set;
+
+    pa_assert(device);
+
+    stream_id_set = pa_intset_new();
+    PA_HASHMAP_FOREACH(sink, device->playback_devices, state) {
+        PA_IDXSET_FOREACH(input, sink->inputs, idx) {
+            p_id_str = pa_proplist_gets(input->proplist, PA_PROP_MEDIA_PARENT_ID);
+            if (p_id_str && !pa_atoi(p_id_str, &p_id)) {
+                pa_intset_put(stream_id_set, p_id);
+            } else {
+                pa_log_warn("Invalid Parent ID : '%s'", pa_strnull(p_id_str));
+            }
+        }
+    }
+    PA_HASHMAP_FOREACH(source, device->capture_devices, state) {
+        PA_IDXSET_FOREACH(output, source->outputs, idx) {
+            p_id_str = pa_proplist_gets(output->proplist, PA_PROP_MEDIA_PARENT_ID);
+            if (p_id_str && !pa_atoi(p_id_str, &p_id)) {
+                pa_intset_put(stream_id_set, p_id);
+            } else {
+                pa_log_warn("Invalid Parent ID : '%s'", pa_strnull(p_id_str));
+            }
+        }
+    }
+
+    return stream_id_set;
+}
+
 static int method_call_bt_sco(pa_dbus_connection *conn, bool onoff) {
     DBusMessage *msg, *reply;
     DBusError err;
index 89b6a85..6a1a027 100644 (file)
@@ -9,8 +9,11 @@
 #include <pulsecore/dbus-util.h>
 #endif
 
+#define MAX_INTSET_NUM 32
+
 typedef struct pa_tz_device pa_tz_device;
 typedef struct pa_tz_device_new_data pa_tz_device_new_data;
+typedef struct pa_intset pa_intset;
 
 /* structures for represent device items which can be connected/disconnected */
 
@@ -124,6 +127,7 @@ dm_device_direction_t pa_tz_device_get_direction(pa_tz_device *device);
 pa_usec_t pa_tz_device_get_creation_time(pa_tz_device *device);
 bool pa_tz_device_is_use_internal_codec(pa_tz_device *device);
 bool pa_tz_device_is_all_suspended(pa_tz_device *device);
+pa_intset* pa_tz_device_get_stream_list(pa_tz_device *device);
 
 /* Only for BT SCO device */
 int pa_tz_device_sco_open(pa_tz_device *device);
@@ -131,4 +135,12 @@ int pa_tz_device_sco_close(pa_tz_device *device);
 int pa_tz_device_sco_get_property(pa_tz_device *device, bool *is_wide_band, bool *nrec);
 int pa_tz_device_sco_get_status(pa_tz_device *device, dm_device_bt_sco_status_t *status);
 
+
+void pa_intset_free(pa_intset *s);
+int pa_intset_first(pa_intset *s, int *val);
+int pa_intset_next(pa_intset *s, int *val);
+
+#define PA_INTSET_FOREACH(i, s, r) \
+    for ((r) = pa_intset_first((s), &(i)); (r == 0); (r) = pa_intset_next((s), &(i)))
+
 #endif