device-manager: handle tunnel device 89/241189/6
authorSeungbae Shin <seungbae.shin@samsung.com>
Tue, 18 Aug 2020 10:36:53 +0000 (19:36 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Wed, 19 Aug 2020 10:36:28 +0000 (19:36 +0900)
tunnel device will be registered(unregistered) when the remote access permission is allowed(denied).
tunnel device will be a network type device

[Version] 13.0.25
[Issue Type] Update

Change-Id: I897fcb5a74ee55c60112e5a9d956c909aae736d0

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

index 9324ca1..3d9e02b 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          13.0.24
+Version:          13.0.25
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index faf4b1d..5e17f2c 100644 (file)
@@ -53,6 +53,8 @@ struct _device_manager {
     pa_hook_slot *comm_hook_device_connection_changed_slot;
     pa_hook_slot *comm_hook_device_state_changed_slot;
     pa_hook_slot *comm_hook_device_running_changed_slot;
+    pa_hook_slot *source_proplist_changed_slot;
+    pa_hook_slot *sink_proplist_changed_slot;
     pa_communicator *comm;
     pa_hal_interface *hal_interface;
 
index 6276308..7fc3435 100644 (file)
@@ -38,6 +38,7 @@
 #include <pulsecore/namereg.h>
 #include <pulsecore/shared.h>
 #include <pulsecore/dynarray.h>
+#include <pulsecore/proplist-util.h>
 
 #include <vconf.h>
 #include <vconf-keys.h>
@@ -80,6 +81,7 @@
 #define DEVICE_API_NULL                     "null"
 #define DEVICE_API_ACM                      "acm"
 #define DEVICE_API_RAOP                     "raop"
+#define DEVICE_API_TUNNEL                   "tunnel"
 #define DEVICE_BUS_USB                      "usb"
 #define DEVICE_CLASS_SOUND                  "sound"
 #define DEVICE_CLASS_MONITOR                "monitor"
@@ -397,6 +399,14 @@ static bool pulse_device_is_raop(pa_object *pdevice) {
     return pa_safe_streq(pa_proplist_gets(prop, PA_PROP_DEVICE_API), DEVICE_API_RAOP);
 }
 
+static bool pulse_device_is_tunnel(pa_object *pdevice) {
+    pa_proplist *prop = pulse_device_get_proplist(pdevice);
+
+    if (!prop)
+        return false;
+
+    return pa_safe_streq(pa_proplist_gets(prop, PA_PROP_DEVICE_API), DEVICE_API_TUNNEL);
+}
 
 static bool pulse_device_is_tizenaudio(pa_object *pdevice) {
     if (!pdevice)
@@ -1140,6 +1150,8 @@ static const char* pulse_device_get_system_id(pa_object *pdevice) {
         return pa_proplist_gets(prop, "bluez.path");
     else if (pulse_device_is_raop(pdevice))
         return pa_proplist_gets(prop, PA_PROP_DEVICE_STRING);
+    else if (pulse_device_is_tunnel(pdevice))
+        return pa_proplist_gets(prop, PA_PROP_DEVICE_DESCRIPTION);
     else
         return NULL;
 }
@@ -1469,6 +1481,43 @@ static void handle_raop_pulse_device(pa_object *pdevice, bool is_loaded, pa_devi
     }
 }
 
+static void handle_tunnel_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *dm) {
+    dm_device_direction_t direction;
+    pa_tz_device *device;
+    const char *system_id;
+
+    pa_assert(pdevice);
+    pa_assert(dm);
+
+    pa_log_info("Handle TUNNEL pulse device");
+
+    direction = pulse_device_get_direction(pdevice);
+    system_id = pulse_device_get_system_id(pdevice);
+
+    if (is_loaded) {
+        pa_tz_device_new_data data;
+
+        pa_proplist *prop = pulse_device_get_proplist(pdevice);
+        const char *name = pa_proplist_gets(prop, PA_PROP_DEVICE_DESCRIPTION);
+
+        pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, dm->dbus_conn);
+        _fill_new_data_basic(&data, DEVICE_TYPE_NETWORK, direction, false, dm);
+        pa_tz_device_new_data_set_name(&data, name);
+        pa_tz_device_new_data_set_system_id(&data, system_id);
+        if (direction == DM_DEVICE_DIRECTION_OUT)
+            pa_tz_device_new_data_add_sink(&data, DEVICE_ROLE_TUNNEL, PA_SINK(pdevice));
+        else
+            pa_tz_device_new_data_add_source(&data, DEVICE_ROLE_TUNNEL, PA_SOURCE(pdevice));
+        pa_tz_device_new(&data);
+        pa_tz_device_new_data_done(&data);
+    } else {
+        if (!(device = device_list_get_device(dm, DEVICE_TYPE_NETWORK, NULL, system_id)))
+            pa_log_warn("Can't get REMOTE device for %s", system_id);
+        else
+            pa_tz_device_free(device);
+    }
+}
+
 static void handle_acm_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *dm) {
     pa_tz_device *device;
 
@@ -1602,6 +1651,18 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, pa_
     } else if (pulse_device_is_raop(PA_OBJECT(sink))) {
         handle_raop_pulse_device(PA_OBJECT(sink), false, dm);
         return PA_HOOK_OK;
+    } else if (pulse_device_is_tunnel(PA_OBJECT(sink))) {
+        if (pa_proplist_has_remote_name(sink->proplist)) {
+            if (pa_proplist_remote_is_allowed(sink->proplist)) {
+                pa_log_info("allowed sink is unlinked, update to deny now");
+                pa_sink_update_proplist_remote_access_permission(sink, false);
+            } else {
+                pa_log_info("denied sink is unlinked, nothing to do");
+            }
+        } else {
+            pa_log_warn("tunnel but not remote....ignore this");
+        }
+        return PA_HOOK_OK;
     } else if (pulse_device_is_acm(PA_OBJECT(sink))) {
         handle_acm_pulse_device(PA_OBJECT(sink), false, dm);
         return PA_HOOK_OK;
@@ -1660,6 +1721,18 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
     } else if (pulse_device_is_bluez(PA_OBJECT(source))) {
         handle_bt_pulse_device(PA_OBJECT(source), false, dm);
         return PA_HOOK_OK;
+    } else if (pulse_device_is_tunnel(PA_OBJECT(source))) {
+        if (pa_proplist_has_remote_name(source->proplist)) {
+            if (pa_proplist_remote_is_allowed(source->proplist)) {
+                pa_log_info("allowed source is unlinked, update to deny now");
+                pa_source_update_proplist_remote_access_permission(source, false);
+            } else {
+                pa_log_info("denied source is unlinked, nothing to do");
+            }
+        } else {
+            pa_log_warn("tunnel but not remote....ignore this");
+        }
+        return PA_HOOK_OK;
     } else if (pulse_device_is_alsa(PA_OBJECT(source)) || pulse_device_is_tizenaudio(PA_OBJECT(source))) {
         handle_internal_pulse_device(PA_OBJECT(source), false, dm);
         return PA_HOOK_OK;
@@ -1698,6 +1771,32 @@ static pa_hook_result_t sink_source_state_changed_hook_cb(pa_core *c, pa_object
     return PA_HOOK_OK;
 }
 
+static pa_hook_result_t source_proplist_changed(pa_core *core, pa_source *source, pa_device_manager *dm) {
+    pa_core_assert_ref(core);
+    pa_source_assert_ref(source);
+
+    if (pulse_device_is_tunnel(PA_OBJECT(source)) &&
+        pa_proplist_has_remote_name(source->proplist)) {
+        /* FIXME : skip if no changes */
+        pulse_device_set_use_internal_codec(PA_OBJECT(source), false);
+        handle_tunnel_pulse_device(PA_OBJECT(source), pa_proplist_remote_is_allowed(source->proplist), dm);
+    }
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_proplist_changed(pa_core *core, pa_sink *sink, pa_device_manager *dm) {
+    pa_core_assert_ref(core);
+    pa_sink_assert_ref(sink);
+
+    if (pulse_device_is_tunnel(PA_OBJECT(sink)) &&
+        pa_proplist_has_remote_name(sink->proplist)) {
+        /* FIXME : skip if no changes */
+        pulse_device_set_use_internal_codec(PA_OBJECT(sink), false);
+        handle_tunnel_pulse_device(PA_OBJECT(sink), pa_proplist_remote_is_allowed(sink->proplist), dm);
+    }
+    return PA_HOOK_OK;
+}
+
 /*
     Build params for load sink or source, and load it.
 */
@@ -2776,9 +2875,13 @@ pa_device_manager* pa_device_manager_get(pa_core *c) {
     dm->sink_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, dm);
     dm->sink_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, dm);
     dm->sink_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_source_state_changed_hook_cb, dm);
+    dm->sink_proplist_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_proplist_changed, dm);
+
     dm->source_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) source_put_hook_callback, dm);
     dm->source_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) source_unlink_hook_callback, dm);
     dm->source_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_source_state_changed_hook_cb, dm);
+    dm->source_proplist_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) source_proplist_changed, dm);
+
     dm->comm = pa_communicator_get(dm->core);
     dm->comm_hook_device_connection_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED),
             PA_HOOK_EARLY, (pa_hook_cb_t)device_connection_changed_hook_cb, dm);
@@ -2843,18 +2946,24 @@ void pa_device_manager_unref(pa_device_manager *dm) {
         pa_hook_slot_free(dm->comm_hook_device_state_changed_slot);
     if (dm->comm_hook_device_running_changed_slot)
         pa_hook_slot_free(dm->comm_hook_device_running_changed_slot);
+
     if (dm->sink_put_hook_slot)
         pa_hook_slot_free(dm->sink_put_hook_slot);
     if (dm->sink_unlink_hook_slot)
         pa_hook_slot_free(dm->sink_unlink_hook_slot);
     if (dm->sink_state_changed_slot)
         pa_hook_slot_free(dm->sink_state_changed_slot);
+    if (dm->sink_proplist_changed_slot)
+        pa_hook_slot_free(dm->sink_proplist_changed_slot);
+
     if (dm->source_put_hook_slot)
         pa_hook_slot_free(dm->source_put_hook_slot);
     if (dm->source_unlink_hook_slot)
         pa_hook_slot_free(dm->source_unlink_hook_slot);
     if (dm->source_state_changed_slot)
         pa_hook_slot_free(dm->source_state_changed_slot);
+    if (dm->source_proplist_changed_slot)
+        pa_hook_slot_free(dm->source_proplist_changed_slot);
 
     if (dm->hal_interface)
         pa_hal_interface_unref(dm->hal_interface);
index ed91400..e4232da 100644 (file)
@@ -27,6 +27,7 @@
 #define DEVICE_ROLE_HIGH_LATENCY            "high-latency"
 #define DEVICE_ROLE_UHQA                    "uhqa"
 #define DEVICE_ROLE_RAOP                    "raop"
+#define DEVICE_ROLE_TUNNEL                  "tunnel"
 #define DEVICE_ROLE_ACM                     "acm"
 
 typedef enum dm_device_direction_type {