On Mon, 2011-05-23 at 18:18 +0100, Colin Guthrie wrote: > How about this: > > Define a new card property similar in concept to > PA_PROP_DEVICE_INTENDED_ROLES ("device.intended_roles") called > PA_PROP_DEVICE_INTENDED_PROFILE ("device.intended_profile"). > > In bluetooth device, when loading a headset that has both HSP and A2DP, > populate the device with the following code: > > if (supports_hsp && supports_a2dp) > { > char *k; > > k = pa_sprintf_malloc("%s.%s", PA_PROP_DEVICE_INTENDED_PROFILE, "music"); > pa_proplist_sets(card_data.proplist, k, "a2dp"); > pa_xfree(k); > > k = pa_sprintf_malloc("%s.%s", PA_PROP_DEVICE_INTENDED_PROFILE, "video"); > pa_proplist_sets(card_data.proplist, k, "a2dp"); > pa_xfree(k); > > k = pa_sprintf_malloc("%s.%s", PA_PROP_DEVICE_INTENDED_PROFILE, "phone"); > pa_proplist_sets(card_data.proplist, k, "hsp"); > pa_xfree(k); > } > > This should result in "pacmd list-cards" dumping a proplist that includes: > > device.intended_profile.music = a2dp > device.intended_profile.video = a2dp > device.intended_profile.phone = hsp > > > > Then a separate module (module-intended-profiles?) could take care of > listening quite generically for streams landing on sink and do the > following logic: > > > if (!si->sink || !si->sink->card) > return PA_HOOK_OK; > > char *role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE); > if (!role) > return PA_HOOK_OK; > > char *k = pa_sprintf_malloc("%s.%s", PA_PROP_DEVICE_INTENDED_PROFILE, role); > pa_card *card = si->sink->card; > char *profile = pa_proplist_gets(card->proplist, k); > pa_xfree(k); > if (!profile) > return PA_HOOK_OK; > > if (!pa_streq(card->active_profile, profile)) { > /* Save the current profile for later restoration */ > ... > > if (pa_card_set_profile(card, profile, FALSE) < 0) > /* Find the sink of this card as the above call will likely have > changed it */ > sink = pa_idxset_first(card->sinks, NULL); > > pa_sink_input_move_to(si, sink, FALSE); > } > > > This code is then completely generic. I'm not 100% sure how well this > will work in practice as there may be some nasty races etc. but I think > this general approach could work... Perhaps others (i.e. Tanu :D) have > better suggestions? If the priority lists would exist already, the module deciding the routing could examine the stream properties and pick the sink+port with the highest priority that can be made available - if the sink+port isn't immediately available, but can be made available, then the routing module would change the profile and port as needed. But the priority lists are not available. I believe the logic that you propose is otherwise good, except that I don't see how the stream could "land" on the bluetooth (a2dp) sink automatically on phone calls. module-bluetooth-device tags only hsp sinks with the phone tag, not a2dp sinks, so module-intended-roles can't do the required magic. If the hsp sink doesn't exist because the a2dp profile is selected, I don't think there's currently any logic to route the stream to the bluetooth sink. If, however, by some magic the phone stream would be routed to the a2dp sink, then I think your proposal would work fine. For better suggestions, I don't think I have any. Except that use the policy framework - Lin posted from an intel.com address, so I assume he or she (sorry, I don't know Chinese names) is working on Meego, and I've thought that Meego got the policy framework from Maemo. In Maemo the routing is handled by module-policy-enforcement (which gets the command to enable the bluetooth-hsp routing mode from the policy framework), and it works pretty nicely for this kind of use cases. -- Tanu