audio: Fix BT sample rate handling properly

This should now support both old and new headsets,
as we rely on codec negotiation in the bluetooth
stack for narrow/wide band switching.

Change-Id: Ie9d308dfc55726fd1591a7d158f610bd267340e6
(cherry picked from commit d462f7b86e957f858959ef5d80fd1744689ee6ea)
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index 169f5c7..c050dd5 100644
--- a/audio/audio_hw.c
+++ b/audio/audio_hw.c
@@ -4139,11 +4139,8 @@
                             value,
                             sizeof(value));
     if (ret >= 0) {
-        /* TODO: Add support in voice calls */
         if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
             adev->voice.bluetooth_wb = true;
-            ALOGI("%s: Implement support for BT SCO wideband calls!!!",
-                  __func__);
         } else {
             adev->voice.bluetooth_wb = false;
         }
@@ -4553,6 +4550,7 @@
     adev->voice.volume = 1.0f;
     adev->voice.bluetooth_nrec = true;
     adev->voice.in_call = false;
+    adev->voice.bluetooth_wb = false;
 
     /* adev->cur_hdmi_channels = 0;  by calloc() */
     adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
diff --git a/audio/voice.c b/audio/voice.c
index ce981c5..a4b6542 100644
--- a/audio/voice.c
+++ b/audio/voice.c
@@ -38,6 +38,17 @@
 #include "audience.h"
 #endif
 
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:    the pointer to the member.
+ * @type:   the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({              \
+    void *__mptr = (void *)(ptr);                   \
+    ((type *)((uintptr_t)__mptr - offsetof(type, member))); })
+
 static struct pcm_config pcm_config_voicecall = {
     .channels = 2,
     .rate = 8000,
@@ -160,6 +171,7 @@
 void start_voice_session_bt_sco(struct voice_session *session)
 {
     struct pcm_config *voice_sco_config;
+    struct voice_data *vdata = container_of(session, struct voice_data, session);
 
     if (session->pcm_sco_rx != NULL || session->pcm_sco_tx != NULL) {
         ALOGW("%s: SCO PCMs already open!\n", __func__);
@@ -168,7 +180,7 @@
 
     ALOGV("%s: Opening SCO PCMs", __func__);
 
-    if (session->wb_amr_type >= 1) {
+    if (vdata->bluetooth_wb) {
         ALOGV("%s: pcm_config wideband", __func__);
         voice_sco_config = &pcm_config_voice_sco_wb;
     } else {
@@ -372,6 +384,12 @@
 
 bool voice_session_uses_wideband(struct voice_session *session)
 {
+    struct voice_data *vdata = container_of(session, struct voice_data, session);
+
+    if (session->out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
+        return vdata->bluetooth_wb;
+    }
+
     return session->wb_amr_type >= 1;
 }