hal: Fix audio leak issue on speaker during A2DP and SCO concurrency.

-To ensure that A2DP stream is suspended before SCO starts, force
route to speaker is done, update the logic to ensure that force
routing to speaker only happens when there is no A2DP device active.
-Ensure that a2dp_start retry happens on routing request if the earlier
start failed.

Change-Id: I29ea0d8857fc4b9d837f9954423861be9b43b9a6
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index d0959e8..4ac94ca 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -788,7 +788,9 @@
 bool audio_extn_a2dp_is_force_device_switch()
 {
     //During encoder reconfiguration mode, force a2dp device switch
-    return a2dp.is_handoff_in_progress;
+    // Or if a2dp device is selected but earlier start failed ( as a2dp
+    // was suspended, force retry.
+    return a2dp.is_handoff_in_progress || !a2dp.a2dp_started;
 }
 
 void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 659b013..1ea6754 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1051,8 +1051,10 @@
             ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
              (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
              (usecase->devices & AUDIO_DEVICE_OUT_USB_DEVICE) ||
-             (force_restart_session)) &&
-             (platform_check_backends_match(snd_device, usecase->out_snd_device))) {
+             (usecase->devices & AUDIO_DEVICE_OUT_ALL_A2DP) ||
+             (usecase->devices & AUDIO_DEVICE_OUT_ALL_SCO)) &&
+             ((force_restart_session) ||
+             (platform_check_backends_match(snd_device, usecase->out_snd_device)))) {
 
                 ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
                     __func__, use_case_table[usecase->id],
@@ -1398,9 +1400,11 @@
     }
 
     // Force all a2dp output devices to reconfigure for proper AFE encode format
+    //Also handle a case where in earlier a2dp start failed as A2DP stream was
+    //in suspended state, hence try to trigger a retry when we again get a routing request.
     if((usecase->stream.out) &&
        (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
-       audio_extn_a2dp_is_force_device_switch()) {
+        audio_extn_a2dp_is_force_device_switch()) {
          ALOGD("Force a2dp device switch to update new encoder config");
          ret = true;
      }
@@ -2607,7 +2611,10 @@
         /* To avoid a2dp to sco overlapping force route BT usecases
          * to speaker based on Phone state
          */
-        if ((val & AUDIO_DEVICE_OUT_ALL_A2DP) &&
+        if ((((val & AUDIO_DEVICE_OUT_SPEAKER) &&
+                  (val & AUDIO_DEVICE_OUT_ALL_A2DP)) ||
+              ((adev->snd_dev_ref_cnt[SND_DEVICE_OUT_BT_A2DP] == 0) &&
+                  (val & AUDIO_DEVICE_OUT_ALL_A2DP))) &&
             ((adev->mode == AUDIO_MODE_RINGTONE) ||
             (adev->mode == AUDIO_MODE_IN_CALL))) {
             ALOGD("Forcing a2dp routing to speaker for ring/call mode");
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 4dd5383..90fffb4 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1368,6 +1368,7 @@
     hw_interface_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
+    hw_interface_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("PROXY_PORT_RX");
 
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
     /*remove ALAC & APE from DSP decoder list based on software decoder availability*/
@@ -4789,6 +4790,14 @@
     int na_mode = platform_get_native_support();
     bool channels_updated = false;
 
+    /*BT devices backend is not configured from HAL hence skip*/
+    if (snd_device == SND_DEVICE_OUT_BT_A2DP ||
+        snd_device == SND_DEVICE_OUT_BT_SCO ||
+        snd_device == SND_DEVICE_OUT_BT_SCO_WB) {
+        backend_change = false;
+        return backend_change;
+    }
+
     backend_idx = platform_get_backend_index(snd_device);
 
     bit_width = backend_cfg->bit_width;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 83a859c..ffcb862 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1207,6 +1207,7 @@
     hw_interface_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
+    hw_interface_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("PROXY_PORT_RX");
 
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
 
@@ -4704,6 +4705,14 @@
     int na_mode = platform_get_native_support();
     bool channels_updated = false;
 
+    /*BT devices backend is not configured from HAL hence skip*/
+    if (snd_device == SND_DEVICE_OUT_BT_A2DP ||
+        snd_device == SND_DEVICE_OUT_BT_SCO ||
+        snd_device == SND_DEVICE_OUT_BT_SCO_WB) {
+        backend_change = false;
+        return backend_change;
+    }
+
     backend_idx = platform_get_backend_index(snd_device);
 
     bit_width = backend_cfg->bit_width;