[pulseaudio-discuss] [PATCH 03/21] bluetooth: Use pa_device_class_t

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Wed Jun 19 08:40:00 PDT 2013


This also fixes the issue that the old code generated form factors
that were not in line with the PA_PROP_DEVICE_FORM_FACTOR
documentation.
---
 src/modules/bluetooth/bluetooth-util.c          | 72 ++++++++-----------
 src/modules/bluetooth/bluetooth-util.h          | 16 +----
 src/modules/bluetooth/module-bluetooth-device.c | 91 ++++++++++---------------
 src/pulsecore/device-class.c                    | 19 ++++++
 src/pulsecore/device-class.h                    | 18 +++++
 5 files changed, 103 insertions(+), 113 deletions(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index 5924736..c5b070c 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -2171,19 +2171,30 @@ pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hoo
     return &y->hooks[hook];
 }
 
-pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class) {
+pa_device_class_t pa_bluetooth_convert_device_class(uint32_t class) {
     unsigned major, minor;
-    pa_bt_form_factor_t r;
-
-    static const pa_bt_form_factor_t table[] = {
-        [1] = PA_BT_FORM_FACTOR_HEADSET,
-        [2] = PA_BT_FORM_FACTOR_HANDSFREE,
-        [4] = PA_BT_FORM_FACTOR_MICROPHONE,
-        [5] = PA_BT_FORM_FACTOR_SPEAKER,
-        [6] = PA_BT_FORM_FACTOR_HEADPHONE,
-        [7] = PA_BT_FORM_FACTOR_PORTABLE,
-        [8] = PA_BT_FORM_FACTOR_CAR,
-        [10] = PA_BT_FORM_FACTOR_HIFI
+    pa_device_class_t r;
+
+    static const pa_device_class_t table[] = {
+        [0] = PA_DEVICE_CLASS_UNKNOWN,
+        [1] = PA_DEVICE_CLASS_HEADSET,
+        [2] = PA_DEVICE_CLASS_HANDSFREE,
+        [3] = PA_DEVICE_CLASS_UNKNOWN,
+        [4] = PA_DEVICE_CLASS_MICROPHONE,
+        [5] = PA_DEVICE_CLASS_SPEAKERS,
+        [6] = PA_DEVICE_CLASS_HEADPHONES,
+        [7] = PA_DEVICE_CLASS_PORTABLE,
+        [8] = PA_DEVICE_CLASS_CAR,
+        [9] = PA_DEVICE_CLASS_SETTOP_BOX,
+        [10] = PA_DEVICE_CLASS_HIFI,
+        [11] = PA_DEVICE_CLASS_VCR,
+        [12] = PA_DEVICE_CLASS_VIDEO_CAMERA,
+        [13] = PA_DEVICE_CLASS_CAMCORDER,
+        [14] = PA_DEVICE_CLASS_UNKNOWN,
+        [15] = PA_DEVICE_CLASS_VIDEO_DISPLAY_AND_SPEAKERS,
+        [16] = PA_DEVICE_CLASS_VIDEO_CONFERENCING,
+        [17] = PA_DEVICE_CLASS_UNKNOWN,
+        [18] = PA_DEVICE_CLASS_GAMING_OR_TOY
     };
 
     /*
@@ -2194,50 +2205,25 @@ pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class) {
     minor = (class >> 2) & 0x3F;
 
     switch (major) {
+        case 1:
+            return PA_DEVICE_CLASS_COMPUTER;
         case 2:
-            return PA_BT_FORM_FACTOR_PHONE;
+            return PA_DEVICE_CLASS_PHONE;
         case 4:
             break;
         default:
             pa_log_debug("Unknown Bluetooth major device class %u", major);
-            return PA_BT_FORM_FACTOR_UNKNOWN;
+            return PA_DEVICE_CLASS_UNKNOWN;
     }
 
-    r = minor < PA_ELEMENTSOF(table) ? table[minor] : PA_BT_FORM_FACTOR_UNKNOWN;
+    r = minor < PA_ELEMENTSOF(table) ? table[minor] : PA_DEVICE_CLASS_UNKNOWN;
 
-    if (!r)
+    if (r == PA_DEVICE_CLASS_UNKNOWN)
         pa_log_debug("Unknown Bluetooth minor device class %u", minor);
 
     return r;
 }
 
-const char *pa_bt_form_factor_to_string(pa_bt_form_factor_t ff) {
-    switch (ff) {
-        case PA_BT_FORM_FACTOR_UNKNOWN:
-            return "unknown";
-        case PA_BT_FORM_FACTOR_HEADSET:
-            return "headset";
-        case PA_BT_FORM_FACTOR_HANDSFREE:
-            return "hands-free";
-        case PA_BT_FORM_FACTOR_MICROPHONE:
-            return "microphone";
-        case PA_BT_FORM_FACTOR_SPEAKER:
-            return "speaker";
-        case PA_BT_FORM_FACTOR_HEADPHONE:
-            return "headphone";
-        case PA_BT_FORM_FACTOR_PORTABLE:
-            return "portable";
-        case PA_BT_FORM_FACTOR_CAR:
-            return "car";
-        case PA_BT_FORM_FACTOR_HIFI:
-            return "hifi";
-        case PA_BT_FORM_FACTOR_PHONE:
-            return "phone";
-    }
-
-    pa_assert_not_reached();
-}
-
 char *pa_bluetooth_cleanup_name(const char *name) {
     char *t, *s, *d;
     bool space = false;
diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h
index 3361b0f..b7842af 100644
--- a/src/modules/bluetooth/bluetooth-util.h
+++ b/src/modules/bluetooth/bluetooth-util.h
@@ -154,21 +154,7 @@ void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t
 
 pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook);
 
-typedef enum pa_bt_form_factor {
-    PA_BT_FORM_FACTOR_UNKNOWN,
-    PA_BT_FORM_FACTOR_HEADSET,
-    PA_BT_FORM_FACTOR_HANDSFREE,
-    PA_BT_FORM_FACTOR_MICROPHONE,
-    PA_BT_FORM_FACTOR_SPEAKER,
-    PA_BT_FORM_FACTOR_HEADPHONE,
-    PA_BT_FORM_FACTOR_PORTABLE,
-    PA_BT_FORM_FACTOR_CAR,
-    PA_BT_FORM_FACTOR_HIFI,
-    PA_BT_FORM_FACTOR_PHONE,
-} pa_bt_form_factor_t;
-
-pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class);
-const char *pa_bt_form_factor_to_string(pa_bt_form_factor_t ff);
+pa_device_class_t pa_bluetooth_convert_device_class(uint32_t class);
 
 char *pa_bluetooth_cleanup_name(const char *name);
 
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index a517e59..aadc260 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -2063,6 +2063,7 @@ off:
 
 /* Run from main thread */
 static void create_card_ports(struct userdata *u, pa_hashmap *ports) {
+    pa_device_class_t device_class;
     pa_device_port *port;
     pa_device_port_new_data port_data;
 
@@ -2070,62 +2071,42 @@ static void create_card_ports(struct userdata *u, pa_hashmap *ports) {
     const char *input_description = NULL;
     const char *output_description = NULL;
 
+    static const char *input_description_table[PA_DEVICE_CLASS_MAX] = {
+        [PA_DEVICE_CLASS_HEADSET] = N_("Headset"),
+        [PA_DEVICE_CLASS_HANDSFREE] = N_("Hands-free"),
+        [PA_DEVICE_CLASS_MICROPHONE] = N_("Microphone"),
+        [PA_DEVICE_CLASS_PORTABLE] = N_("Portable"),
+        [PA_DEVICE_CLASS_CAR] = N_("Car"),
+        [PA_DEVICE_CLASS_SETTOP_BOX] = N_("Set-top Box"),
+        [PA_DEVICE_CLASS_HIFI] = N_("HiFi"),
+        [PA_DEVICE_CLASS_VCR] = N_("VCR"),
+        [PA_DEVICE_CLASS_VIDEO_CAMERA] = N_("Video Camera"),
+        [PA_DEVICE_CLASS_CAMCORDER] = N_("Camcorder"),
+        [PA_DEVICE_CLASS_VIDEO_CONFERENCING] = N_("Video Conferencing")
+    };
+
+    static const char *output_description_table[PA_DEVICE_CLASS_MAX] = {
+        [PA_DEVICE_CLASS_HEADSET] = N_("Headset"),
+        [PA_DEVICE_CLASS_HANDSFREE] = N_("Hands-free"),
+        [PA_DEVICE_CLASS_SPEAKERS] = N_("Speakers"),
+        [PA_DEVICE_CLASS_HEADPHONES] = N_("Headphones"),
+        [PA_DEVICE_CLASS_PORTABLE] = N_("Portable"),
+        [PA_DEVICE_CLASS_CAR] = N_("Car"),
+        [PA_DEVICE_CLASS_SETTOP_BOX] = N_("Set-top Box"),
+        [PA_DEVICE_CLASS_HIFI] = N_("HiFi"),
+        [PA_DEVICE_CLASS_VCR] = N_("VCR"),
+        [PA_DEVICE_CLASS_VIDEO_DISPLAY_AND_SPEAKERS] = N_("Video Display and Speakers"),
+        [PA_DEVICE_CLASS_VIDEO_CONFERENCING] = N_("Video Conferencing")
+    };
+
     pa_assert(u);
     pa_assert(ports);
     pa_assert(u->device);
 
-    switch (pa_bluetooth_get_form_factor(u->device->class)) {
-        case PA_BT_FORM_FACTOR_UNKNOWN:
-            break;
-
-        case PA_BT_FORM_FACTOR_HEADSET:
-            name_prefix = "headset";
-            input_description = output_description = _("Headset");
-            break;
-
-        case PA_BT_FORM_FACTOR_HANDSFREE:
-            name_prefix = "handsfree";
-            input_description = output_description = _("Handsfree");
-            break;
-
-        case PA_BT_FORM_FACTOR_MICROPHONE:
-            name_prefix = "microphone";
-            input_description = _("Microphone");
-            break;
-
-        case PA_BT_FORM_FACTOR_SPEAKER:
-            name_prefix = "speaker";
-            output_description = _("Speaker");
-            break;
-
-        case PA_BT_FORM_FACTOR_HEADPHONE:
-            name_prefix = "headphone";
-            output_description = _("Headphone");
-            break;
-
-        case PA_BT_FORM_FACTOR_PORTABLE:
-            name_prefix = "portable";
-            input_description = output_description = _("Portable");
-            break;
-
-        case PA_BT_FORM_FACTOR_CAR:
-            name_prefix = "car";
-            input_description = output_description = _("Car");
-            break;
-
-        case PA_BT_FORM_FACTOR_HIFI:
-            name_prefix = "hifi";
-            input_description = output_description = _("HiFi");
-            break;
-
-        case PA_BT_FORM_FACTOR_PHONE:
-            name_prefix = "phone";
-            input_description = output_description = _("Phone");
-            break;
-    }
-
-    if (!name_prefix)
-        name_prefix = "unknown";
+    device_class = pa_bluetooth_convert_device_class(u->device->class);
+    name_prefix = pa_device_class_to_string(device_class);
+    input_description = input_description_table[device_class];
+    output_description = output_description_table[device_class];
 
     if (!output_description)
         output_description = _("Bluetooth Output");
@@ -2230,8 +2211,8 @@ static int add_card(struct userdata *u) {
     bool b;
     pa_card_profile *p;
     enum profile *d;
-    pa_bt_form_factor_t ff;
     char *n;
+    const char *form_factor;
     const char *default_profile;
     const pa_bluetooth_device *device;
     const pa_bluetooth_uuid *uuid;
@@ -2253,8 +2234,8 @@ static int add_card(struct userdata *u) {
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth");
 
-    if ((ff = pa_bluetooth_get_form_factor(device->class)) != PA_BT_FORM_FACTOR_UNKNOWN)
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, pa_bt_form_factor_to_string(ff));
+    if ((form_factor = pa_device_class_to_form_factor_string(pa_bluetooth_convert_device_class(device->class))))
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, form_factor);
 
     pa_proplist_sets(data.proplist, "bluez.path", device->path);
     pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", (unsigned) device->class);
diff --git a/src/pulsecore/device-class.c b/src/pulsecore/device-class.c
index 73f20ae..4b90992 100644
--- a/src/pulsecore/device-class.c
+++ b/src/pulsecore/device-class.c
@@ -51,6 +51,21 @@ static const char * const string_table[PA_DEVICE_CLASS_MAX] = {
     [PA_DEVICE_CLASS_TUNER] = "tuner"
 };
 
+static const char * const form_factor_table[PA_DEVICE_CLASS_MAX] = {
+    [PA_DEVICE_CLASS_COMPUTER] = "computer",
+    [PA_DEVICE_CLASS_PHONE] = "handset",
+    [PA_DEVICE_CLASS_HEADSET] = "headset",
+    [PA_DEVICE_CLASS_HANDSFREE] = "hands-free",
+    [PA_DEVICE_CLASS_MICROPHONE] = "microphone",
+    [PA_DEVICE_CLASS_SPEAKERS] = "speaker",
+    [PA_DEVICE_CLASS_HEADPHONES] = "headphone",
+    [PA_DEVICE_CLASS_PORTABLE] = "portable",
+    [PA_DEVICE_CLASS_CAR] = "car",
+    [PA_DEVICE_CLASS_HIFI] = "hifi",
+    [PA_DEVICE_CLASS_VIDEO_CAMERA] = "webcam",
+    [PA_DEVICE_CLASS_VIDEO_DISPLAY_AND_SPEAKERS] = "tv"
+};
+
 pa_device_class_t pa_device_class_from_string(const char *str) {
     unsigned i;
 
@@ -67,3 +82,7 @@ pa_device_class_t pa_device_class_from_string(const char *str) {
 const char *pa_device_class_to_string(pa_device_class_t class) {
     return string_table[class];
 }
+
+const char *pa_device_class_to_form_factor_string(pa_device_class_t class) {
+    return form_factor_table[class];
+}
diff --git a/src/pulsecore/device-class.h b/src/pulsecore/device-class.h
index e820fc2..a459db2 100644
--- a/src/pulsecore/device-class.h
+++ b/src/pulsecore/device-class.h
@@ -67,4 +67,22 @@ typedef enum {
 pa_device_class_t pa_device_class_from_string(const char *str);
 const char *pa_device_class_to_string(pa_device_class_t class);
 
+/* This function produces a string that is suitable to be used as the
+ * PA_PROP_DEVICE_FORM_FACTOR property. Not all device classes are suitable,
+ * because the documentation for the property defines a fixed list of possible
+ * values, and that list doesn't contain all the device classes that we have
+ * available. If the device class can't be converted to one of the listed form
+ * factors, this function returns NULL.
+ *
+ * We possibly could change the documentation of the DEVICE_FORM_FACTOR
+ * property, but that would be strictly speaking an ABI break. Also, it's quite
+ * nice to have a device class enumeration that isn't exposed to clients,
+ * because it allows us to easily tune the enumeration contents without
+ * worrying about client compatibility, so I'm not eager to force the device
+ * class enumeration to be the same thing as the form factor property, even if
+ * they are pretty similar (also note that they may be similar, but definitely
+ * not the same thing, because e.g. "tuner" is a valid device class, but not a
+ * form factor). */
+const char *pa_device_class_to_form_factor_string(pa_device_class_t class);
+
 #endif
-- 
1.8.1.2



More information about the pulseaudio-discuss mailing list