sthal: handle multiple rx stream for bargein

Bug: 144538590
Test: Verify the functionality and related use-cases regression
validation by tester team.
Change-Id: I0d0a9dd2fced840bb4060615f413e34802b3ed96
diff --git a/sound_trigger_hw_iaxxx.c b/sound_trigger_hw_iaxxx.c
index 0652389..6b15f4b 100644
--- a/sound_trigger_hw_iaxxx.c
+++ b/sound_trigger_hw_iaxxx.c
@@ -162,7 +162,6 @@
 
     int last_detected_model_type;
     bool is_mic_route_enabled;
-    bool is_music_playing;
     bool is_bargein_route_enabled;
     bool is_chre_loaded;
     bool is_buffer_package_loaded;
@@ -184,6 +183,7 @@
 
     unsigned int current_enable;
     unsigned int recover_model_list;
+    unsigned int rx_active_count;
     transit_case_t transit_case;
 
     struct audio_route *route_hdl;
@@ -1050,10 +1050,10 @@
 static int async_setup_aec(struct knowles_sound_trigger_device *stdev)
 {
     int ret = 0;
-    if (stdev->is_music_playing == true &&
+    if (stdev->rx_active_count > 0 &&
         stdev->is_bargein_route_enabled != true &&
         stdev->is_mic_route_enabled != false) {
-        ALOGD("%s: Bargein enable", __func__);
+        ALOGD("%s: Bargein enabling", __func__);
         if (is_mic_controlled_by_ahal(stdev) == false) {
             ret = enable_mic_route(stdev->route_hdl, false,
                                 INTERNAL_OSCILLATOR);
@@ -1157,6 +1157,8 @@
                 }
             }
         }
+    } else {
+        ALOGD("%s: Bargein is already enabled", __func__);
     }
 
 exit:
@@ -1170,7 +1172,7 @@
     enum clock_type ct = INTERNAL_OSCILLATOR;
     enum strm_type strmt = STRM_16K;
 
-    if (stdev->is_music_playing == true) {
+    if (stdev->rx_active_count > 0) {
         ct = EXTERNAL_OSCILLATOR;
     }
 
@@ -1200,7 +1202,7 @@
                 goto exit;
             }
         }
-        if (stdev->is_music_playing == true &&
+        if (stdev->rx_active_count > 0 &&
             stdev->is_bargein_route_enabled == false) {
             err = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
             if (err != 0) {
@@ -1246,7 +1248,7 @@
     } else {
         if (!is_any_model_active(stdev)) {
             ALOGD("None of keywords are active");
-            if (stdev->is_music_playing == true &&
+            if (stdev->rx_active_count > 0 &&
                 stdev->is_bargein_route_enabled == true) {
                 // Just disable the route and update the route status but retain
                 // bargein status
@@ -1310,6 +1312,31 @@
     return err;
 }
 
+static void update_rx_conditions(struct knowles_sound_trigger_device *stdev,
+                                 audio_event_type_t event,
+                                 struct audio_event_info *config)
+{
+    if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
+        if (stdev->rx_active_count > 0) {
+            stdev->rx_active_count--;
+        } else {
+            ALOGW("%s: unexpected rx inactive event", __func__);
+        }
+    } else if (event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
+        if (!(config->device_info.device & AUDIO_DEVICE_OUT_SPEAKER)) {
+            ALOGD("%s: Playback device doesn't include SPEAKER.",
+                  __func__);
+        } else {
+            stdev->rx_active_count++;
+        }
+    } else {
+        ALOGW("%s: invalid event %d", __func__, event);
+    }
+    ALOGD("%s: updated rx_concurrency as %d", __func__,
+          stdev->rx_active_count);
+}
+
+
 static void update_sthal_conditions(struct knowles_sound_trigger_device *stdev,
                                     audio_event_type_t event,
                                     struct audio_event_info *config)
@@ -1568,9 +1595,18 @@
     stdev->hotword_buffer_enable = 0;
     stdev->music_buffer_enable = 0;
 
-    if (stdev->is_music_playing == true &&
+    if (stdev->rx_active_count == 0 &&
         stdev->is_bargein_route_enabled == true) {
-        ct = EXTERNAL_OSCILLATOR;
+        /* rx stream is disabled during codec recovery.
+         * Need to reset the enabled flag
+         */
+        stdev->is_bargein_route_enabled = false;
+    } else if (stdev->rx_active_count > 0 &&
+               stdev->is_bargein_route_enabled == false) {
+        /* rx stream is enabled during codec recovery.
+         * Need to raise the enabled flag
+         */
+        stdev->is_bargein_route_enabled = true;
     }
 
     if (stdev->is_buffer_package_loaded == true) {
@@ -1627,8 +1663,9 @@
         }
     }
 
-    if (stdev->is_music_playing == true &&
+    if (stdev->rx_active_count > 0 &&
         stdev->is_bargein_route_enabled == true) {
+        ct = EXTERNAL_OSCILLATOR;
         if (is_mic_controlled_by_ahal(stdev) == true) {
             strmt = STRM_48K;
         }
@@ -2524,6 +2561,7 @@
     }
     if (can_update_recover_list(stdev) == true) {
         update_recover_list(stdev, handle, false);
+        model->is_active = false;
         goto exit;
     }
 
@@ -3411,7 +3449,6 @@
     stdev->is_ahal_in_voice_voip_mode = false;
     stdev->is_ahal_voice_voip_stop = false;
     stdev->is_ahal_voice_voip_start = false;
-    stdev->is_music_playing = false;
     stdev->is_bargein_route_enabled = false;
     stdev->is_chre_loaded = false;
     stdev->is_buffer_package_loaded = false;
@@ -3420,6 +3457,7 @@
     stdev->current_enable = 0;
     stdev->is_sensor_route_enabled = false;
     stdev->recover_model_list = 0;
+    stdev->rx_active_count = 0;
     stdev->is_ahal_media_recording = false;
     stdev->is_concurrent_capture = hw_properties.concurrent_capture;
 
@@ -3514,6 +3552,12 @@
         cur_mode = get_sthal_mode(stdev);
     }
 
+    // update conditions for bargein whatever firmware status may be.
+    if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE ||
+        event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
+        update_rx_conditions(stdev, event, config);
+    }
+
     if (stdev->is_st_hal_ready == false) {
         ALOGE("%s: ST HAL is not ready yet", __func__);
         ret = -EINVAL;
@@ -3538,14 +3582,13 @@
     case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
         ALOGD("%s: handle playback stream inactive", __func__);
 
-        if (stdev->is_music_playing != false) {
-            stdev->is_music_playing = false;
+        if (stdev->rx_active_count == 0) {
             if (stdev->is_mic_route_enabled != false) {
                 // Atleast one keyword model is active so update the routes
                 // Check if the bargein route is enabled if not enable bargein route
                 // Check each model, if it is active then update it's route
                 if (stdev->is_bargein_route_enabled != false) {
-                    ALOGD("Bargein disable");
+                    ALOGD("Bargein disabling");
                     stdev->is_bargein_route_enabled = false;
                     // Check each model, if it is active then update it's route
                     // Disable the bargein route
@@ -3651,21 +3694,18 @@
                             goto exit;
                         }
                     }
+                } else {
+                    ALOGW("%s: barge-in isn't enabled", __func__);
                 }
             }
         } else {
-            ALOGD("%s: STHAL setup playback Inactive alrealy", __func__);
+            ALOGD("%s: rx stream is still active", __func__);
         }
         break;
     case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
         ALOGD("%s: handle playback stream active", __func__);
-        if (!(config->device_info.device & AUDIO_DEVICE_OUT_SPEAKER)) {
-            ALOGD("%s: Playback device doesn't include SPEAKER.",
-                __func__);
-            goto exit;
-        }
-        if (stdev->is_music_playing != true) {
-            stdev->is_music_playing = true;
+
+        if (stdev->rx_active_count > 0) {
             if (stdev->is_mic_route_enabled != false) {
                 // Atleast one keyword model is active so update the routes
                 // Check if the bargein route is enabled if not enable bargein route
@@ -3674,7 +3714,7 @@
                 pthread_cond_signal(&stdev->transition_cond);
             }
         } else {
-            ALOGD("%s: STHAL setup playback active alrealy", __func__);
+            ALOGW("%s: unexpeted stream active event", __func__);
         }
         break;
     case AUDIO_EVENT_STOP_LAB: