Handle codec negotiation failed.

If the codec negotiation fails, we never reset current scb
which results in stack being in BTA_AG_SCO_LISTEN_ST and
new connections transfered instead of opened.
As transfers are ignored in listen state, no sco could be
opened until the first device failing negotiation was
disconnected.

Handling the BTA_AG_SCO_CLOSE_E (result of a negotiation
failed) in order to remove the current scb and let other
devices open sco.

There are no current tests for the SCO state machine, so
keeping this change behind a flag until then.

Bug: 265582589
Tag: #feature
Test: Manual, forced codec nego timeout. Behind a flag.
Change-Id: Ic73cc0d44a5d966e4353012f170d5a664799074c
diff --git a/system/bta/ag/bta_ag_sco.cc b/system/bta/ag/bta_ag_sco.cc
index 6701c92..5361158 100644
--- a/system/bta/ag/bta_ag_sco.cc
+++ b/system/bta/ag/bta_ag_sco.cc
@@ -30,6 +30,7 @@
 #include "bt_target.h"  // Must be first to define build configuration
 #include "bt_trace.h"   // Legacy trace logging
 #include "bta/ag/bta_ag_int.h"
+#include "common/init_flags.h"
 #include "device/include/controller.h"
 #include "main/shim/dumpsys.h"
 #include "osi/include/log.h"
@@ -766,6 +767,15 @@
           break;
 
         case BTA_AG_SCO_CLOSE_E:
+          if (bluetooth::common::init_flags::
+                  sco_codec_timeout_clear_is_enabled()) {
+            /* remove listening connection */
+            bta_ag_remove_sco(p_scb, false);
+
+            if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
+
+            bta_ag_create_sco(p_scb, false);
+          }
           /* sco open is not started yet. just go back to listening */
           p_sco->state = BTA_AG_SCO_LISTEN_ST;
           break;
diff --git a/system/gd/rust/common/src/init_flags.rs b/system/gd/rust/common/src/init_flags.rs
index c5f81ad..4cdf12d 100644
--- a/system/gd/rust/common/src/init_flags.rs
+++ b/system/gd/rust/common/src/init_flags.rs
@@ -391,6 +391,7 @@
         read_encryption_key_size = true,
         redact_log = true,
         rust_event_loop = true,
+        sco_codec_timeout_clear,
         sdp_serialization = true,
         sdp_skip_rnr_if_known = true,
         bluetooth_quality_report_callback = true,
diff --git a/system/gd/rust/shim/src/init_flags.rs b/system/gd/rust/shim/src/init_flags.rs
index 8ecb2b4..5b01239 100644
--- a/system/gd/rust/shim/src/init_flags.rs
+++ b/system/gd/rust/shim/src/init_flags.rs
@@ -45,6 +45,7 @@
         fn read_encryption_key_size_is_enabled() -> bool;
         fn redact_log_is_enabled() -> bool;
         fn rust_event_loop_is_enabled() -> bool;
+        fn sco_codec_timeout_clear_is_enabled() -> bool;
         fn sdp_serialization_is_enabled() -> bool;
         fn sdp_skip_rnr_if_known_is_enabled() -> bool;
         fn bluetooth_quality_report_callback_is_enabled() -> bool;