Merge "pal: add handling for disconnecting fe after error in startAbr"
diff --git a/device/src/Bluetooth.cpp b/device/src/Bluetooth.cpp
index f002ef4..505c6fa 100644
--- a/device/src/Bluetooth.cpp
+++ b/device/src/Bluetooth.cpp
@@ -655,10 +655,12 @@
     std::vector <std::pair<int, int>> keyVector;
     struct pcm_config config;
     struct mixer_ctl *connectCtrl = NULL;
+    struct mixer_ctl *disconnectCtrl = NULL;
     struct mixer_ctl *btSetFeedbackChannelCtrl = NULL;
     struct mixer *virtualMixerHandle = NULL;
     struct mixer *hwMixerHandle = NULL;
     std::ostringstream connectCtrlName;
+    std::ostringstream disconnectCtrlName;
     unsigned int flags;
     uint32_t codecTagId = 0, miid = 0;
     void *pluginLibHandle = NULL;
@@ -779,12 +781,12 @@
     if (!btSetFeedbackChannelCtrl) {
         PAL_ERR(LOG_TAG, "ERROR %s mixer control not identified",
                 MIXER_SET_FEEDBACK_CHANNEL);
-        goto free_fe;
+        goto disconnect_fe;
     }
 
     if (mixer_ctl_set_value(btSetFeedbackChannelCtrl, 0, 1) != 0) {
         PAL_ERR(LOG_TAG, "Failed to set BT usecase");
-        goto free_fe;
+        goto disconnect_fe;
     }
 
     if (codecFormat == CODEC_TYPE_APTX_AD_SPEECH) {
@@ -793,7 +795,7 @@
         fbDev = std::dynamic_pointer_cast<BtSco>(BtSco::getInstance(&fbDevice, rm));
         if (!fbDev) {
             PAL_ERR(LOG_TAG, "failed to get BtSco singleton object.");
-            goto free_fe;
+            goto disconnect_fe;
         }
 
         fbDev->lockDeviceMutex();
@@ -809,19 +811,19 @@
                      fbpcmDevIds.at(0), backEndName.c_str(), codecTagId, &miid);
         if (ret) {
             PAL_ERR(LOG_TAG, "getMiid for feedback device failed");
-            goto free_fe;
+            goto disconnect_fe;
         }
 
         ret = getPluginPayload(&pluginLibHandle, &codec, &out_buf, (codecType == DEC ? ENC : DEC));
         if (ret) {
             PAL_ERR(LOG_TAG, "getPluginPayload failed");
-            goto free_fe;
+            goto disconnect_fe;
         }
 
         /* SWB Encoder/Decoder has only 1 param, read block 0 */
         if (out_buf->num_blks != 1) {
             PAL_ERR(LOG_TAG, "incorrect block size %d", out_buf->num_blks);
-            goto free_fe;
+            goto disconnect_fe;
         }
         fbDev->codecConfig.sample_rate = out_buf->sample_rate;
         fbDev->codecConfig.bit_width = out_buf->bit_format;
@@ -838,7 +840,7 @@
         if (!paramData) {
             PAL_ERR(LOG_TAG, "Failed to populateAPMHeader");
             ret = -ENOMEM;
-            goto free_fe;
+            goto disconnect_fe;
         }
 
         ret = SessionAlsaUtils::setDeviceCustomPayload(rm, backEndName,
@@ -846,7 +848,7 @@
         free(paramData);
         if (ret) {
             PAL_ERR(LOG_TAG, "Error: Dev setParam failed for %d", fbDevice.id);
-            goto free_fe;
+            goto disconnect_fe;
         }
     } else if ((codecFormat == CODEC_TYPE_LC3) ||
                (codecFormat == CODEC_TYPE_APTX_AD_QLEA)) {
@@ -857,7 +859,7 @@
             fbDev = std::dynamic_pointer_cast<BtSco>(BtSco::getInstance(&fbDevice, rm));
             if (!fbDev) {
                 PAL_ERR(LOG_TAG, "failed to get BtSco singleton object.");
-                goto free_fe;
+                goto disconnect_fe;
             }
         } else if ((fbDevice.id == PAL_DEVICE_IN_BLUETOOTH_A2DP) ||
                    (fbDevice.id == PAL_DEVICE_OUT_BLUETOOTH_BLE) ||
@@ -865,7 +867,7 @@
             fbDev = std::dynamic_pointer_cast<BtA2dp>(BtA2dp::getInstance(&fbDevice, rm));
             if (!fbDev) {
                 PAL_ERR(LOG_TAG, "failed to get BtA2dp singleton object.");
-                goto free_fe;
+                goto disconnect_fe;
             }
         }
 
@@ -892,7 +894,7 @@
             if (ret) {
                 PAL_ERR(LOG_TAG, "Failed to get tag info %x, ret = %d",
                         COP_DEPACKETIZER_V2, ret);
-                goto free_fe;
+                goto disconnect_fe;
             }
 
             // intentionally configure depacketizer in the same manner as configuring packetizer
@@ -900,7 +902,7 @@
             if (!paramData) {
                 PAL_ERR(LOG_TAG, "Invalid COPv2 module param size");
                 ret = -EINVAL;
-                goto free_fe;
+                goto disconnect_fe;
             }
 
             ret = SessionAlsaUtils::setDeviceCustomPayload(rm, backEndName,
@@ -908,7 +910,7 @@
             delete [] paramData;
             if (ret) {
                 PAL_ERR(LOG_TAG, "Error: Dev setParam failed for %d", fbDevice.id);
-                goto free_fe;
+                goto disconnect_fe;
             }
         } else if ((fbDevice.id == PAL_DEVICE_IN_BLUETOOTH_SCO_HEADSET) ||
                    (fbDevice.id == PAL_DEVICE_OUT_BLUETOOTH_SCO) ||
@@ -920,7 +922,7 @@
                          fbpcmDevIds.at(0), backEndName.c_str(), codecTagId, &miid);
             if (ret) {
                 PAL_ERR(LOG_TAG, "getMiid for feedback device failed");
-                goto free_fe;
+                goto disconnect_fe;
             }
 
             if (isEncDecConfigured) {
@@ -928,7 +930,7 @@
                                       (codecType == DEC ? ENC : DEC));
                 if (ret) {
                     PAL_ERR(LOG_TAG, "getPluginPayload failed");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
             } else {
                 /* In case of BLE stereorecording/voice_call_decode_session, only decoder
@@ -943,13 +945,13 @@
                                        (codecType == DEC ? ENC : DEC));
                 if (ret) {
                     PAL_ERR(LOG_TAG, "getPluginPayload failed");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
             }
 
             if (out_buf->num_blks != 1) {
                 PAL_ERR(LOG_TAG, "incorrect block size %d", out_buf->num_blks);
-                goto free_fe;
+                goto disconnect_fe;
             }
             fbDev->codecConfig.sample_rate = out_buf->sample_rate;
             fbDev->codecConfig.bit_width = out_buf->bit_format;
@@ -967,7 +969,7 @@
             } else {
                 ret = -EINVAL;
                 PAL_ERR(LOG_TAG, "Failed to populateAPMHeader");
-                goto free_fe;
+                goto disconnect_fe;
             }
 
             codec->close_plugin(codec);
@@ -980,7 +982,7 @@
                 if (ret) {
                     PAL_ERR(LOG_TAG, "Failed to get tag info %x, ret = %d",
                             COP_DEPACKETIZER_V2, ret);
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
 
                 builder->payloadCopV2DepackConfig(&paramData, &paramSize, miid, codecInfo, false /* StreamMapOut */);
@@ -992,7 +994,7 @@
                 } else {
                     ret = -EINVAL;
                     PAL_ERR(LOG_TAG, "Invalid COPv2 module param size");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
 
                 builder->payloadCopV2DepackConfig(&paramData, &paramSize, miid, codecInfo, true /* StreamMapIn */);
@@ -1004,7 +1006,7 @@
                 } else {
                     ret = -EINVAL;
                     PAL_ERR(LOG_TAG, "Invalid COPv2 module param size");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
             } else { /* fbDevice.id == PAL_DEVICE_OUT_BLUETOOTH_SCO ||
                       * fbDevice.id == PAL_DEVICE_OUT_BLUETOOTH_BLE*/
@@ -1014,7 +1016,7 @@
                 if (ret) {
                     PAL_ERR(LOG_TAG, "Failed to get tag info %x, ret = %d",
                             COP_PACKETIZER_V2, ret);
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
 
                 // PARAM_ID_COP_V2_STREAM_INFO for COPv2
@@ -1027,7 +1029,7 @@
                 } else {
                     ret = -EINVAL;
                     PAL_ERR(LOG_TAG, "Invalid COPv2 module param size");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
 
                 // PARAM_ID_COP_PACKETIZER_OUTPUT_MEDIA_FORMAT for COPv2
@@ -1040,7 +1042,7 @@
                 } else {
                     ret = -EINVAL;
                     PAL_ERR(LOG_TAG, "Invalid COP module param size");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
             }
 
@@ -1049,7 +1051,7 @@
                          fbpcmDevIds.at(0), backEndName.c_str(), RAT_RENDER, &miid);
             if (ret) {
                 PAL_ERR(LOG_TAG, "Failed to get tag info %x, ret = %d", RAT_RENDER, ret);
-                goto free_fe;
+                goto disconnect_fe;
             } else {
                 builder->payloadRATConfig(&paramData, &paramSize, miid, &fbDev->codecConfig);
                 if (paramSize) {
@@ -1060,7 +1062,7 @@
                 } else {
                     ret = -EINVAL;
                     PAL_ERR(LOG_TAG, "Invalid RAT module param size");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
             }
 
@@ -1069,7 +1071,7 @@
                          fbpcmDevIds.at(0), backEndName.c_str(), BT_PCM_CONVERTER, &miid);
             if (ret) {
                 PAL_ERR(LOG_TAG, "Failed to get tag info %x, ret = %d", BT_PCM_CONVERTER, ret);
-                goto free_fe;
+                goto disconnect_fe;
             } else {
                 builder->payloadPcmCnvConfig(&paramData, &paramSize, miid, &fbDev->codecConfig,
                         (codecType == DEC ? true : false) /* isRx */);
@@ -1081,7 +1083,7 @@
                 } else {
                     ret = -EINVAL;
                     PAL_ERR(LOG_TAG, "Invalid PCM CNV module param size");
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
             }
 
@@ -1090,7 +1092,7 @@
                                             fbDev->customPayload, fbDev->customPayloadSize);
                 if (ret) {
                     PAL_ERR(LOG_TAG, "Error: Dev setParam failed for %d", fbDevice.id);
-                    goto free_fe;
+                    goto disconnect_fe;
                 }
 
                 if (fbDev->customPayload) {
@@ -1114,7 +1116,7 @@
     fbPcm = pcm_open(rm->getVirtualSndCard(), fbpcmDevIds.at(0), flags, &config);
     if (!fbPcm) {
         PAL_ERR(LOG_TAG, "pcm open failed");
-        goto free_fe;
+        goto disconnect_fe;
     }
 
     if (!pcm_is_ready(fbPcm)) {
@@ -1153,6 +1155,12 @@
 err_pcm_open:
     pcm_close(fbPcm);
     fbPcm = NULL;
+disconnect_fe:
+    disconnectCtrlName << "PCM" << fbpcmDevIds.at(0) << " disconnect";
+    disconnectCtrl = mixer_get_ctl_by_name(virtualMixerHandle, disconnectCtrlName.str().data());
+    if(disconnectCtrl != NULL){
+       mixer_ctl_set_enum_by_string(disconnectCtrl, backEndName.c_str());
+    }
 free_fe:
     rm->freeFrontEndIds(fbpcmDevIds, sAttr, dir);
     fbpcmDevIds.clear();