added support for manually loaded HDMI and jack alsa sinks
authorJanos Kovacs <jko@ivi2.ka.intel.com>
Thu, 17 Jan 2013 22:24:25 +0000 (00:24 +0200)
committerJanos Kovacs <jko@ivi2.ka.intel.com>
Thu, 17 Jan 2013 22:24:25 +0000 (00:24 +0200)
Makefile.am
murphy/Makefile.am
murphy/classify.c
murphy/classify.h
murphy/discover.c
murphy/node.h
murphy/router.c
murphy/userdata.h
murphy/volume.c

index 38844a3..ea13bec 100644 (file)
@@ -7,4 +7,5 @@ MAINTAINERCLEANFILES = \
         build-stamp compile depcomp acinclude.m4 aclocal.m4 \
        stamp-h1 
 
+
 clean-local:
index 295fd53..c4625ed 100644 (file)
@@ -61,4 +61,3 @@ module_murphy_ivi_la_CFLAGS = $(AM_CFLAGS) $(CONDITIONAL_CFLAGS)            \
                               $(LIBPULSE_CFLAGS) $(PULSEDEVEL_CFLAGS)       \
                               $(MURPHYCOMMON_CFLAGS) $(MURPHYDOMCTL_CFLAGS) \
                               $(LUAUTILS_CFLAGS) $(LUA_CFLAGS)
-
index fdda594..d00ffcc 100644 (file)
@@ -175,6 +175,36 @@ void pa_classify_node_by_card(mir_node        *node,
     }
 }
 
+pa_bool_t pa_classify_node_by_property(mir_node *node, pa_proplist *pl)
+{
+    typedef struct {
+        const char *name;
+        mir_node_type value;
+    } type_mapping_t;
+
+    static type_mapping_t  map[] = {
+        {"jack", mir_jack},
+        {"hdmi", mir_hdmi},
+        {NULL, mir_node_type_unknown}
+    };
+
+    const char *type;
+    int i;
+
+    pa_assert(node);
+    pa_assert(pl);
+
+    if ((type = pa_proplist_gets(pl, PA_PROP_NODE_TYPE))) {
+        for (i = 0; map[i].name;  i++) {
+            if (pa_streq(type, map[i].name)) {
+                node->type = map[i].value;
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
 
 /* data->direction must be set */
 void pa_classify_guess_device_node_type_and_name(mir_node   *node,
@@ -359,3 +389,11 @@ const char *pa_classify_loopback_stream(mir_node *node)
 
     return NULL;
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
index f283db3..4b1957a 100644 (file)
@@ -26,6 +26,7 @@
 
 void pa_classify_node_by_card(mir_node *, pa_card *, pa_card_profile *,
                               pa_device_port *);
+pa_bool_t pa_classify_node_by_property(mir_node *, pa_proplist *);
 void pa_classify_guess_device_node_type_and_name(mir_node*, const char *,
                                                  const char *);
 mir_node_type pa_classify_guess_stream_node_type(pa_proplist *);
index dcb93a6..9d96102 100644 (file)
@@ -485,20 +485,27 @@ void pa_discover_add_sink(struct userdata *u, pa_sink *sink, pa_bool_t route)
         data.direction = mir_output;
         data.implement = mir_device;
         data.channels  = sink->channel_map.channels;
+        data.available = TRUE;
+        data.paidx     = sink->index;
 
         if (sink == pa_utils_get_null_sink(u)) {
             data.visible = FALSE;
-            data.available = TRUE;
             data.type = mir_null;
             data.amname = pa_xstrdup("Silent");
             data.amid = AM_ID_INVALID;
             data.paname = pa_xstrdup(sink->name);
-            data.paidx = sink->index;
+        }
+        else if (pa_classify_node_by_property(&data, sink->proplist)) {
+            data.privacy = mir_public;
+            data.visible = TRUE;
+            data.amname = pa_xstrdup(mir_node_type_str(data.type));
+            data.amid = AM_ID_INVALID;
+            data.paname = pa_xstrdup(sink->name);
         }
         else {
             pa_xfree(data.key); /* for now */
-            pa_log_info("currently we do not support "
-                        "statically loaded sinks");
+            pa_log_info("currently we do not support statically loaded "
+                        "sinks without " PA_PROP_NODE_TYPE " property");
             return;
         }
 
@@ -612,10 +619,16 @@ void pa_discover_add_source(struct userdata *u, pa_source *source)
             data.paname = pa_xstrdup(source->name);
             data.paidx = source->index;
         }
+        else if (pa_classify_node_by_property(&data, source->proplist)) {
+            data.visible = TRUE;
+            data.amname = pa_xstrdup(mir_node_type_str(data.type));
+            data.amid = AM_ID_INVALID;
+            data.paname = pa_xstrdup(source->name);
+        }
         else {
             pa_xfree(data.key); /* for now */
-            pa_log_info("currently we do not support "
-                        "statically loaded sources");
+            pa_log_info("currently we do not support statically loaded "
+                        "sources without " PA_PROP_NODE_TYPE " property");
             return;
         }
 
index 9e7d4e9..80d129d 100644 (file)
@@ -74,8 +74,8 @@ enum mir_node_type {
     mir_rear_speakers,
     mir_microphone,
     mir_jack,
-    mir_spdif,
     mir_hdmi,
+    mir_spdif,
     mir_wired_headset,
     mir_wired_headphone,
     mir_usb_headset,
index 8ba16ee..464f7fb 100644 (file)
@@ -521,17 +521,42 @@ void mir_router_make_routing(struct userdata *u)
 pa_bool_t mir_router_default_accept(struct userdata *u, mir_rtgroup *rtg,
                                     mir_node *node)
 {
+    pa_core *core;
+    pa_sink *sink;
+    pa_source *source;
+    pa_proplist *pl;
+    mir_node_type class;
     pa_bool_t accept;
+    const char *role, *excluded_role;
 
     pa_assert(u);
     pa_assert(rtg);
     pa_assert(node);
 
-    if (node->type == mir_bluetooth_carkit)
+    class = node->type;
+
+    if (class == mir_bluetooth_carkit)
         accept = FALSE;
-    else
-        accept = (node->type >= mir_device_class_begin &&
-                  node->type < mir_device_class_end);
+    else if (class == mir_jack || class == mir_hdmi) {
+        pa_assert_se((core = u->core));
+            
+        if (node->direction == mir_input) {
+            source = pa_idxset_get_by_index(core->sources,node->paidx);
+            pl = source ? source->proplist : NULL;
+            excluded_role = "hfp_uplink";
+        }
+        else {
+            sink = pa_idxset_get_by_index(core->sinks, node->paidx);
+            pl = sink ? sink->proplist : NULL;
+            excluded_role = "hfp_downlink";
+        }
+        role = pl ? pa_proplist_gets(pl, PA_PROP_NODE_ROLE) : NULL;
+        accept = role ? strcmp(role, excluded_role) : TRUE;
+    }
+    else {
+        accept = (class >= mir_device_class_begin &&
+                  class < mir_device_class_end);
+    }
         
     return accept;
 }
@@ -540,7 +565,12 @@ pa_bool_t mir_router_default_accept(struct userdata *u, mir_rtgroup *rtg,
 pa_bool_t mir_router_phone_accept(struct userdata *u, mir_rtgroup *rtg,
                                   mir_node *node)
 {
+    pa_core *core;
+    pa_sink *sink;
+    pa_source *source;
+    pa_proplist *pl;
     mir_node_type class;
+    const char *role, *expected_role;
 
     pa_assert(u);
     pa_assert(rtg);
@@ -552,13 +582,31 @@ pa_bool_t mir_router_phone_accept(struct userdata *u, mir_rtgroup *rtg,
         if (class != mir_bluetooth_a2dp   &&
             class != mir_usb_headphone    &&
             class != mir_wired_headphone  &&
-            class != mir_jack             &&
-            class != mir_hdmi             &&
             class != mir_spdif            &&
             class != mir_bluetooth_source &&
             class != mir_bluetooth_sink   &&
             class != mir_bluetooth_carkit   )
         {
+            if (class == mir_jack || class == mir_hdmi) {
+                pa_assert_se((core = u->core));
+
+                if (node->direction == mir_input) {
+                    source = pa_idxset_get_by_index(core->sources,node->paidx);
+                    pl = source ? source->proplist : NULL;
+                    expected_role = "hfp_uplink";
+                }
+                else {
+                    sink = pa_idxset_get_by_index(core->sinks, node->paidx);
+                    pl = sink ? sink->proplist : NULL;
+                    expected_role = "hfp_downlink";
+                }
+                if (!pl || !(role = pa_proplist_gets(pl, PA_PROP_NODE_ROLE)) ||
+                    strcmp(role, expected_role))
+                {
+                    return FALSE;
+                }
+            }
+
             return TRUE;
         }
     }
index 528b497..fcb0bc3 100644 (file)
@@ -37,6 +37,8 @@
 #define PA_PROP_ROUTING_METHOD         "routing.method"
 #define PA_PROP_ROUTING_TABLE          "routing.table"
 #define PA_PROP_NODE_INDEX             "node.index"
+#define PA_PROP_NODE_TYPE              "node.type"
+#define PA_PROP_NODE_ROLE              "node.role"
 
 #define PA_ROUTING_DEFAULT             "default"
 #define PA_ROUTING_EXPLICIT            "explicit"
index 19a67dd..8306045 100644 (file)
@@ -248,8 +248,12 @@ double mir_volume_correction(struct userdata *u, int class, mir_node *node,
     pa_assert(u);
     pa_assert(node);
 
-    if (arg && node->implement == mir_device && node->privacy == mir_public)
+    if (arg && *(double **)arg &&
+        node->implement == mir_device &&
+        node->privacy == mir_public)
+    {
         return **(double **)arg;
+    }
 
     return 0.0;
 }