hal: force device switch when BT SCO is off

When BT SCO is off, the active use cases may still stay on SCO
devices which is not expected, switch the device to handset or
handset mic before receiving routing command from audio policy
manager.
Also, reset SCO configuration for SWB device only when BT SCO
is off, as the path needs to keep active to allow starting
playback/capture for multiple times during SCO is on.

Change-Id: I5817824fd921b2d5f9e17ee8aed02d0bd2cee0fc
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 19c839c..e07a5ca 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -3016,9 +3016,11 @@
 
 void sco_reset_configuration()
 {
-    ALOGD("sco_reset_configuration start");
+    if (a2dp.swb_configured) {
+        ALOGD("sco_reset_configuration start");
 
-    reset_codec_config();
-    a2dp.bt_encoder_format = CODEC_TYPE_INVALID;
-    a2dp.swb_configured = false;
+        reset_codec_config();
+        a2dp.bt_encoder_format = CODEC_TYPE_INVALID;
+        a2dp.swb_configured = false;
+    }
 }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9f90d93..047696f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1289,14 +1289,7 @@
             audio_extn_a2dp_stop_playback();
         else if (snd_device == SND_DEVICE_IN_BT_A2DP)
             audio_extn_a2dp_stop_capture();
-        else if ((snd_device == SND_DEVICE_OUT_BT_SCO_SWB) ||
-                 (snd_device == SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC) ||
-                 (snd_device == SND_DEVICE_IN_BT_SCO_MIC_SWB)) {
-            if ((adev->snd_dev_ref_cnt[SND_DEVICE_OUT_BT_SCO_SWB] == 0) &&
-                (adev->snd_dev_ref_cnt[SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC] == 0) &&
-                (adev->snd_dev_ref_cnt[SND_DEVICE_IN_BT_SCO_MIC_SWB] == 0))
-                audio_extn_sco_reset_configuration();
-       } else if ((snd_device == SND_DEVICE_OUT_HDMI) ||
+        else if ((snd_device == SND_DEVICE_OUT_HDMI) ||
                 (snd_device == SND_DEVICE_OUT_DISPLAY_PORT))
             adev->is_channel_status_set = false;
         else if ((snd_device == SND_DEVICE_OUT_HEADPHONES) &&
@@ -7601,6 +7594,8 @@
     int ret;
     int status = 0;
     bool a2dp_reconfig = false;
+    struct listnode *node;
+    struct audio_usecase *usecase = NULL;
 
     ALOGD("%s: enter: %s", __func__, kvpairs);
     parms = str_parms_create_str(kvpairs);
@@ -7608,16 +7603,31 @@
     if (!parms)
         goto error;
 
+    pthread_mutex_lock(&adev->lock);
     ret = str_parms_get_str(parms, "BT_SCO", value, sizeof(value));
     if (ret >= 0) {
         /* When set to false, HAL should disable EC and NS */
-        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
+        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0){
             adev->bt_sco_on = true;
-        else
+        } else {
+            ALOGD("sco is off, reset sco and route device to handset/mic");
             adev->bt_sco_on = false;
+            audio_extn_sco_reset_configuration();
+            list_for_each(node, &adev->usecase_list) {
+                usecase = node_to_item(node, struct audio_usecase, list);
+                if ((usecase->type == PCM_PLAYBACK) && usecase->stream.out &&
+                    (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_SCO))
+                    usecase->stream.out->devices = AUDIO_DEVICE_OUT_EARPIECE;
+                else if ((usecase->type == PCM_CAPTURE) && usecase->stream.in &&
+                         (usecase->stream.in->device & AUDIO_DEVICE_IN_ALL_SCO))
+                    usecase->stream.in->device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+                else
+                    continue;
+                select_devices(adev, usecase->id);
+            }
+        }
     }
 
-    pthread_mutex_lock(&adev->lock);
     status = voice_set_parameters(adev, parms);
     if (status != 0)
         goto done;