finer granularity of amname generation + audio manager registration filtering 61/26861/3
authorJanos Kovacs <jankovac503@gmail.com>
Fri, 16 May 2014 12:00:51 +0000 (15:00 +0300)
committerJaska Uimonen <jaska.uimonen@helsinki.fi>
Fri, 29 Aug 2014 14:13:55 +0000 (17:13 +0300)
Change-Id: Ie4a31093f5966fb8bf2a46cad338ba8c1cbec0d7

murphy/audiomgr.c
murphy/classify.c
murphy/discover.c
murphy/node.c
murphy/node.h
murphy/utils.c
murphy/utils.h

index 23552d7..dd31ee0 100644 (file)
@@ -213,53 +213,90 @@ void pa_audiomgr_unregister_domain(struct userdata *u, bool send_state)
     am->domain.state = DS_DOWN;
 }
 
+void fill_am_data_and_register(struct userdata *u, mir_node *node, pa_audiomgr *am)
+{
+    am_nodereg_data  *rd;
+    am_method         method;
+    bool              success;
+
+    rd = pa_xnew0(am_nodereg_data, 1);
+    rd->key     = pa_xstrdup(node->key);
+    rd->name    = pa_xstrdup(node->amname);
+    rd->domain  = am->domain.id;
+    rd->class   = 0x43;
+    rd->volume  = 32767;
+    rd->visible = node->visible;
+    rd->avail.status = AS_AVAILABLE;
+    rd->avail.reason = 0;
+    rd->mainvol = 32767;
+
+    if (node->direction == mir_input) {
+        rd->interrupt = IS_OFF;
+        method = audiomgr_register_source;
+    }
+    else {
+        rd->mute = MS_UNMUTED;
+        method = audiomgr_register_sink;
+    }
+
+    success = pa_routerif_register_node(u, method, rd);
+
+    if (success) {
+        pa_log_debug("initiate registration node '%s' (%p)"
+                     "to audio manager", rd->name, node);
+    }
+    else {
+        pa_log("%s: failed to register node '%s' (%p)"
+               "to audio manager", __FILE__, rd->name, node);
+    }
+
+    return;
+}
 
 void pa_audiomgr_register_node(struct userdata *u, mir_node *node)
 {
+    static const char *classes_to_register[] = {
+        "wrtApplication",
+        "icoApplication",
+        "navigator",
+        "phone",
+        "radio",
+        NULL
+    };
+
     pa_audiomgr      *am;
-    am_nodereg_data  *rd;
-    am_method         method;
-    bool         success;
+    bool              success;
+    const char       *class_to_register;
+    int               i;
 
     pa_assert(u);
     pa_assert_se((am = u->audiomgr));
 
-    if (am->domain.state == DS_DOWN || am->domain.state == DS_RUNDOWN)
+    if (am->domain.state == DS_DOWN || am->domain.state == DS_RUNDOWN) {
         pa_log_debug("skip registering nodes while the domain is down");
-    else {
-        if (node->direction == mir_input || node->direction == mir_output) {
-            rd = pa_xnew0(am_nodereg_data, 1);
-            rd->key     = pa_xstrdup(node->key);
-            rd->name    = pa_xstrdup(node->amname);
-            rd->domain  = am->domain.id;
-            rd->class   = 0x43;
-            rd->volume  = 32767;
-            rd->visible = node->visible;
-            rd->avail.status = AS_AVAILABLE;
-            rd->avail.reason = 0;
-            rd->mainvol = 32767;
-
-            if (node->direction == mir_input) {
-                rd->interrupt = IS_OFF;
-                method = audiomgr_register_source;
-            }
-            else {
-                rd->mute = MS_UNMUTED;
-                method = audiomgr_register_sink;
+        return;
+    }
+
+    for (i = 0;   (class_to_register = classes_to_register[i]);   i++) {
+        if (!strcmp(node->amname, class_to_register)) {
+            if (node->direction == mir_input || node->direction == mir_output){
+                fill_am_data_and_register(u, node, am);
             }
 
-            success = pa_routerif_register_node(u, method, rd);
+            return;
+        }
+    } /* for classes_to_register */
 
-            if (success) {
-                pa_log_debug("initiate registration node '%s' (%p)"
-                             "to audio manager", rd->name, node);
-            }
-            else {
-                pa_log("%s: failed to register node '%s' (%p)"
-                       "to audio manager", __FILE__, rd->name, node);
-            }
+    /* ok, register also the gateways */
+    if (strncmp(node->amname, "gw", 2) == 0) {
+        if (node->direction == mir_input || node->direction == mir_output){
+            fill_am_data_and_register(u, node, am);
         }
+        return;
     }
+
+    pa_log_debug("skip registration of node '%s' (%p): "
+                 "not known by audio manager", node->amname, node);
 }
 
 void pa_audiomgr_node_registered(struct userdata *u,
@@ -289,8 +326,13 @@ void pa_audiomgr_node_registered(struct userdata *u,
 
         pa_hashmap_put(am->nodes, key, node);
 
+        /* we don't want implicit connections register and confuse */
+        /* audio manager. Implicit connections are handled by      */
+        /* creating a resource through murphy */
+        /*
         if (find_default_route(u, node, &cd))
             pa_routerif_register_implicit_connection(u, &cd);
+        */
     }
 
     pa_xfree((void *)rd->key);
@@ -463,8 +505,13 @@ void pa_audiomgr_send_default_routes(struct userdata *u)
         cd->format = link->channels >= 2 ? CF_STEREO : CF_MONO;
     }
 
+    /* we don't want implicit connections register and confuse */
+    /* audio manager. Implicit connections are handled by      */
+    /* creating a resource through murphy */
+    /*
     if (ncd > 0)
         pa_routerif_register_implicit_connections(u, ncd, cds);
+    */
 
 #undef MAX_DEFAULT_ROUTES
 }
index 156e342..d46e2b7 100644 (file)
@@ -213,14 +213,16 @@ bool pa_classify_node_by_property(mir_node *node, pa_proplist *pl)
     } type_mapping_t;
 
     static type_mapping_t  map[] = {
-        {"speakers"      , mir_speakers         },
-        {"front-speakers", mir_front_speakers   },
-        {"rear-speakers" , mir_rear_speakers    },
-        {"microphone"    , mir_microphone       },
-        {"jack"          , mir_jack             },
-        {"hdmi"          , mir_hdmi             },
-        {"spdif"         , mir_spdif            },
-        { NULL           , mir_node_type_unknown}
+        {"speakers"       , mir_speakers         },
+        {"front-speakers" , mir_front_speakers   },
+        {"rear-speakers"  , mir_rear_speakers    },
+        {"microphone"     , mir_microphone       },
+        {"jack"           , mir_jack             },
+        {"hdmi"           , mir_hdmi             },
+        {"gateway_source" , mir_gateway_source   },
+        {"gateway_sink"   , mir_gateway_sink     },
+        {"spdif"          , mir_spdif            },
+        { NULL            , mir_node_type_unknown}
     };
 
     const char *type;
@@ -311,7 +313,10 @@ mir_node_type pa_classify_guess_stream_node_type(struct userdata *u,
         }
 
         if ((bin = pa_proplist_gets(pl, PA_PROP_APPLICATION_PROCESS_BINARY))) {
-            if (!strcmp(bin, "threaded-ml") || !strcmp(bin, "WebProcess") || !strcmp(bin,"wrt_launchpad_daemon")) {
+            if (!strcmp(bin, "threaded-ml") ||
+                !strcmp(bin, "WebProcess")  ||
+                !strcmp(bin,"wrt_launchpad_daemon"))
+            {
                 if (!pid)
                     break;
 
index 8f82243..9458db1 100644 (file)
@@ -118,6 +118,7 @@ static pa_source *make_input_prerouting(struct userdata *, mir_node *,
                                         const char *, mir_node **);
 
 static mir_node_type get_stream_routing_class(pa_proplist *);
+static char *get_stream_amname(mir_node_type, char *, pa_proplist *);
 
 static void set_bluetooth_profile(struct userdata *, pa_card *, pa_direction_t);
 
@@ -179,7 +180,9 @@ void pa_discover_domain_up(struct userdata *u)
     PA_HASHMAP_FOREACH(node, discover->nodes.byname, state) {
         node->amid = AM_ID_INVALID;
 
-        if (node->visible && node->available) {
+        if ((node->visible && node->available) ||
+            (node->type == mir_gateway_sink ||
+             node->type == mir_gateway_source)) {
             pa_audiomgr_register_node(u, node);
             extapi_signal_node_change(u);
         }
@@ -536,11 +539,20 @@ void pa_discover_add_sink(struct userdata *u, pa_sink *sink, bool route)
             data.paname = pa_xstrdup(sink->name);
         }
         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);
+            if (data.type == mir_gateway_sink) {
+                data.privacy = mir_private;
+                data.visible = false;
+                data.amname = pa_xstrdup(sink->name);
+                data.amid = AM_ID_INVALID;
+                data.paname = pa_xstrdup(sink->name);
+            }
+            else {
+                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);
+            }
 
             add_to_hash = true;
         }
@@ -685,10 +697,20 @@ void pa_discover_add_source(struct userdata *u, pa_source *source)
             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);
+            if (data.type == mir_gateway_source) {
+                data.privacy = mir_private;
+                data.visible = false;
+                data.amname = pa_xstrdup(source->name);
+                data.amid = AM_ID_INVALID;
+                data.paname = pa_xstrdup(source->name);
+            }
+            else {
+                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(source->name);
+            }
         }
         else {
             pa_xfree(data.key); /* for now */
@@ -701,7 +723,6 @@ void pa_discover_add_source(struct userdata *u, pa_source *source)
     }
 }
 
-
 void pa_discover_remove_source(struct userdata *u, pa_source *source)
 {
     pa_discover    *discover;
@@ -798,7 +819,7 @@ void pa_discover_register_sink_input(struct userdata *u, pa_sink_input *sinp)
     data.zone      = pa_utils_get_zone(sinp->proplist);
     data.visible   = true;
     data.available = true;
-    data.amname    = name;
+    data.amname    = get_stream_amname(type, name, pl);
     data.amdescr   = (char *)pa_proplist_gets(pl, PA_PROP_MEDIA_NAME);
     data.amid      = AM_ID_INVALID;
     data.paname    = name;
@@ -1059,7 +1080,7 @@ void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp)
         data.zone      = pa_utils_get_zone(pl);
         data.visible   = true;
         data.available = true;
-        data.amname    = name;
+        data.amname    = get_stream_amname(type, name, pl);
         data.amdescr   = (char *)pa_proplist_gets(pl, PA_PROP_MEDIA_NAME);
         data.amid      = AM_ID_INVALID;
         data.paname    = name;
@@ -1112,7 +1133,7 @@ void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp)
 
         /* FIXME: register explicit routes */
         /* else pa_audiomgr_add/register_explicit_route() */
-        
+
 
         pa_fader_apply_volume_limits(u, pa_utils_get_stamp());
     }
@@ -1723,7 +1744,7 @@ static void handle_bluetooth_card(struct userdata *u, pa_card *card)
                 output = false;
             else if (len >= 7 && !strcmp("-output", port->name + (len-7)))
                 input  = false;
-            
+
 
             PA_HASHMAP_FOREACH(prof, port->profiles, state1) {
                 data.pacard.profile = prof->name;
@@ -2308,6 +2329,40 @@ static mir_node_type get_stream_routing_class(pa_proplist *pl)
     return mir_node_type_unknown;
 }
 
+static char *get_stream_amname(mir_node_type type, char *name, pa_proplist *pl)
+{
+    const char *appid;
+
+    switch (type) {
+
+    case mir_radio:
+        return "radio";
+
+    case mir_player:
+    case mir_game:
+    case mir_browser:
+    case mir_camera:
+        appid = pa_utils_get_appid(pl);
+
+        if (!strcmp(appid, "threaded-ml")         ||
+            !strcmp(appid, "WebProcess")          ||
+            !strcmp(appid,"wrt_launchpad_daemon")  )
+        {
+            return "wrtApplication";
+        }
+        return "icoApplication";
+
+    case mir_navigator:
+        return "navigator";
+
+    case mir_phone:
+        return "phone";
+
+    default:
+        return name;
+    }
+}
+
 
 static void set_bluetooth_profile(struct userdata *u,
                                   pa_card *card,
@@ -2387,7 +2442,7 @@ static void set_bluetooth_profile(struct userdata *u,
             else {
                 pa_log_debug("Set profile %s", make_active->name);
 
-                if ((prof = pa_hashmap_get(card->profiles, make_active->name)) != NULL && 
+                if ((prof = pa_hashmap_get(card->profiles, make_active->name)) != NULL &&
                     pa_card_set_profile(card, prof, false) < 0) {
                     pa_log_debug("Failed to change profile to %s",
                                  make_active->name);
index 1d8fb8b..cc06e90 100644 (file)
@@ -510,6 +510,8 @@ const char *mir_node_type_str(mir_node_type type)
     case mir_bluetooth_a2dp:      return "Bluetooth Stereo Headphone";
     case mir_bluetooth_source:    return "Bluetooth Source";
     case mir_bluetooth_sink:      return "Bluetooth Sink";
+    case mir_gateway_sink:        return "Gateway Sink";
+    case mir_gateway_source:      return "Gateway Source";
     default:                      return "<user defined>";
     }
 }
index 331639c..37271d0 100644 (file)
@@ -84,6 +84,8 @@ enum mir_node_type {
     mir_bluetooth_carkit,
     mir_bluetooth_source,
     mir_bluetooth_sink,
+    mir_gateway_sink,
+    mir_gateway_source,
     mir_device_class_end,
 
     /* extensions */
@@ -138,10 +140,10 @@ struct mir_node {
     mir_privacy    privacy;   /**< mir_public | mir_private */
     mir_node_type  type;      /**< mir_speakers | mir_headset | ...  */
     char          *zone;      /**< zone where the node belong */
-    bool      visible;   /**< internal or can appear on UI  */
-    bool      available; /**< eg. is the headset connected?  */
-    bool      ignore;    /**< do not consider it while routing  */
-    bool      localrset; /**< locally generated resource set */
+    bool           visible;   /**< internal or can appear on UI  */
+    bool           available; /**< eg. is the headset connected?  */
+    bool           ignore;    /**< do not consider it while routing  */
+    bool           localrset; /**< locally generated resource set */
     char          *amname;    /**< audiomanager name */
     char          *amdescr;   /**< UI description */
     uint16_t       amid;      /**< handle to audiomanager, if any */
index 96e1e58..43aa75e 100644 (file)
@@ -227,6 +227,16 @@ char *pa_utils_get_zone(pa_proplist *pl)
     return (char *)zone;
 }
 
+const char *pa_utils_get_appid(pa_proplist *pl)
+{
+    const char *appid;
+
+    if (pl && (appid = pa_proplist_gets(pl, PA_PROP_RESOURCE_SET_APPID)))
+        return appid;
+
+    return "<unknown>";
+}
+
 bool pa_utils_set_stream_routing_properties(pa_proplist *pl,
                                                  int          styp,
                                                  void        *target)
index c73be6e..e0c345c 100644 (file)
@@ -40,6 +40,7 @@ char *pa_utils_get_source_output_name(pa_source_output *);
 char *pa_utils_get_source_output_name_from_data(pa_source_output_new_data *);
 
 char *pa_utils_get_zone(pa_proplist *);
+const char *pa_utils_get_appid(pa_proplist *);
 
 bool pa_utils_set_stream_routing_properties(pa_proplist *, int, void *);
 bool pa_utils_unset_stream_routing_properties(pa_proplist *);