[automerger skipped] Merge rvc-qpr-dev-plus-aosp-without-vendor@6881855 am: 27a9b76aa2 -s ours am: dc3d294533 -s ours

am skip reason: Change-Id I62dd37dbbe959f869225f57dda0504fd31546e53 with SHA-1 c2510cab63 is in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/qcom/audio/+/13121833

Change-Id: Ib4dac23a5dfb7973344dcd31cd578522d5416b9a
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index d7e2e2a..d594dc0 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -1424,6 +1424,7 @@
         if (ret != 0 ) {
            ALOGE("%s: Bluetooth controller start failed", __func__);
            a2dp.a2dp_started = false;
+           ret = -ETIMEDOUT;
         } else {
            if (configure_a2dp_encoder_format() == true) {
                 a2dp.a2dp_started = true;
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index 5079233..3b92d14 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -20,6 +20,7 @@
 #include <audio_hw.h>
 #include <cutils/str_parms.h>
 #include <dlfcn.h>
+#include <fcntl.h>
 #include <log/log.h>
 #include <math.h>
 #include <platform_api.h>
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index a3abb8a..fa03a41 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -803,10 +803,13 @@
 
         ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
 
-        if (is_a2dp_device(snd_device) &&
-            (audio_extn_a2dp_start_playback() < 0)) {
-               ALOGE("%s: failed to configure A2DP control path", __func__);
-               goto on_error;
+        if (is_a2dp_device(snd_device)) {
+            if (audio_extn_a2dp_start_playback() < 0) {
+                ALOGE("%s: failed to configure A2DP control path", __func__);
+                goto on_error;
+            } else {
+                adev->a2dp_started = true;
+            }
         }
 
         audio_route_apply_and_update_path(adev->audio_route, device_name);
@@ -839,9 +842,10 @@
     if (adev->snd_dev_ref_cnt[snd_device] == 0) {
         audio_extn_dsm_feedback_enable(adev, snd_device, false);
 
-        if (is_a2dp_device(snd_device))
+        if (is_a2dp_device(snd_device)) {
             audio_extn_a2dp_stop_playback();
-
+            adev->a2dp_started = false;
+        }
         if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
             snd_device == SND_DEVICE_OUT_SPEAKER_SAFE ||
             snd_device == SND_DEVICE_OUT_SPEAKER_REVERSE ||
@@ -2469,16 +2473,13 @@
     }
 
     if (out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
-        if (!audio_extn_a2dp_is_ready()) {
-            if (out->devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
-                a2dp_combo = true;
-            } else {
-                if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
-                    ALOGE("%s: A2DP profile is not ready, return error", __func__);
-                    ret = -EAGAIN;
-                    goto error_config;
-                }
-            }
+        if (out->devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+            a2dp_combo = true;
+        } else if (!audio_extn_a2dp_is_ready() &&
+                !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
+            ALOGE("%s: A2DP profile is not ready, return error", __func__);
+            ret = -EAGAIN;
+            goto error_config;
         }
     }
     out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
@@ -2511,11 +2512,14 @@
     audio_streaming_hint_start();
     audio_extn_perf_lock_acquire();
 
+    if (!(out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) ||
+            audio_extn_a2dp_is_ready()) {
+        select_devices(adev, out->usecase);
+    }
+
     if ((out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
-        (!audio_extn_a2dp_is_ready())) {
-        if (!a2dp_combo) {
-            check_a2dp_restore_l(adev, out, false);
-        } else {
+            (!audio_extn_a2dp_is_ready() || !adev->a2dp_started)) {
+        if (a2dp_combo) {
             audio_devices_t dev = out->devices;
             if (dev & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
                 out->devices = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
@@ -2523,9 +2527,13 @@
                 out->devices = AUDIO_DEVICE_OUT_SPEAKER;
             select_devices(adev, out->usecase);
             out->devices = dev;
+        } else if (!audio_extn_a2dp_is_ready()) {
+            check_a2dp_restore_l(adev, out, false);
+        } else {
+            ALOGE("%s: A2DP is not started, return error", __func__);
+            ret = -EINVAL;
+            goto error_open;
         }
-    } else {
-         select_devices(adev, out->usecase);
     }
 
     audio_extn_extspk_update(adev->extspk);
@@ -6604,6 +6612,7 @@
     adev->primary_output = NULL;
     adev->bluetooth_nrec = true;
     adev->acdb_settings = TTY_MODE_OFF;
+    adev->a2dp_started = false;
     /* adev->cur_hdmi_channels = 0;  by calloc() */
     adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
     voice_init(adev);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index e980e88..b709b1d 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -431,6 +431,7 @@
     snd_device_t last_logged_snd_device[AUDIO_USECASE_MAX][2]; /* [out, in] */
     int camera_orientation; /* CAMERA_BACK_LANDSCAPE ... CAMERA_FRONT_PORTRAIT */
     bool bt_sco_on;
+    bool a2dp_started;
 };
 
 int select_devices(struct audio_device *adev,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 8fa9826..2d35365 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -19,6 +19,7 @@
 
 #include <stdlib.h>
 #include <dlfcn.h>
+#include <fcntl.h>
 #include <pthread.h>
 #include <unistd.h>
 #include <log/log.h>