Merge f6cc050e7da66d3f42a561f2ca3f1a87be72e86b on remote branch

Change-Id: Ie0f1b18827bd485cca42e9ade32445e9316bc3cb
diff --git a/sound_trigger_hw.c b/sound_trigger_hw.c
index f677147..54d26d7 100644
--- a/sound_trigger_hw.c
+++ b/sound_trigger_hw.c
@@ -1246,8 +1246,8 @@
              platform_stdev_compare_device_type(&stdev->active_rx_dev_list,
                  AUDIO_DEVICE_OUT_SPEAKER) ||
              platform_stdev_compare_device_type(&stdev->active_rx_dev_list,
-                 AUDIO_DEVICE_IN_WIRED_HEADSET))) {
-
+                 AUDIO_DEVICE_IN_WIRED_HEADSET)) &&
+             stdev->session_allowed) {
             /* pause and resume ADSP sessions to send new echo reference */
             list_for_each(node, &stdev->sound_model_list) {
                 p_ses = node_to_item(node, st_session_t, list_node);
diff --git a/sound_trigger_platform.c b/sound_trigger_platform.c
index 4fb305a..36f296f 100644
--- a/sound_trigger_platform.c
+++ b/sound_trigger_platform.c
@@ -4669,7 +4669,7 @@
 {
     struct platform_data *my_data;
     sound_trigger_device_t *stdev;
-    bool concurrency_ses_allowed = false;
+    bool concurrency_ses_allowed = true;
 
     if (!platform) {
         ALOGE("%s: NULL platform", __func__);
@@ -4723,13 +4723,12 @@
         }
         if (event_type == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE ||
             event_type == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
-            concurrency_ses_allowed = true;
             if (stdev->rx_concurrency_disabled &&
                 stdev->rx_concurrency_active > 0 &&
                 num_sessions > stdev->rx_conc_max_st_ses)
                 concurrency_ses_allowed = false;
-        } else if (stdev->conc_capture_supported) {
-            concurrency_ses_allowed = true;
+        }
+        if (concurrency_ses_allowed && stdev->conc_capture_supported) {
             if ((!stdev->conc_voice_call_supported && stdev->conc_voice_active) ||
                 (!stdev->conc_voip_call_supported && stdev->conc_voip_active))
                 concurrency_ses_allowed = false;
@@ -4757,8 +4756,8 @@
         }
         if (stdev->conc_capture_supported)
             concurrency_ses_allowed = stdev->session_allowed;
-        else if (stdev->tx_concurrency_active == 0)
-            concurrency_ses_allowed = true;
+        else if (stdev->tx_concurrency_active > 0)
+            concurrency_ses_allowed = false;
     }
 
     /*
@@ -5692,10 +5691,12 @@
     if (is_ec_profile(profile_type)) {
         event_info.st_ec_ref_enabled = enable;
         // reset the pending active EC mixer ctls first
-        if (!stdev->audio_ec_enabled && stdev->ec_reset_pending_cnt > 0) {
-            while (stdev->ec_reset_pending_cnt--)
+        if (!stdev->audio_ec_enabled) {
+            while (stdev->ec_reset_pending_cnt > 0) {
                 audio_route_reset_and_update_path(stdev->audio_route,
                         my_data->ec_ref_mixer_path);
+                stdev->ec_reset_pending_cnt--;
+            }
         }
         if (enable) {
             stdev->audio_hal_cb(ST_EVENT_UPDATE_ECHO_REF, &event_info);
diff --git a/st_session.c b/st_session.c
index 2ae2d81..9b6d5c6 100644
--- a/st_session.c
+++ b/st_session.c
@@ -2646,7 +2646,12 @@
         st_ses->hw_session_started = true;
     } else {
         ALOGE("%s:[%d] failed to restart", __func__, st_ses->sm_handle);
-        st_ses->hw_session_started = false;
+        /*
+         * lower layers like gcs/lsm need to handle double stop calls properly
+         * to avoid possible crash, as some of the clean ups are already issued
+         * during fptrs->restart() when it's failed.
+         */
+        stop_hw_session(st_ses, hw_ses, true);
     }
 
     return status;
@@ -4591,6 +4596,11 @@
         STATE_TRANSITION(st_ses, loaded_state_fn);
         break;
 
+    case ST_SES_EV_RESUME:
+        if (stc_ses->paused == true)
+            stc_ses->paused = false;
+        break;
+
     case ST_SES_EV_STOP:
         status = stop_session(st_ses, hw_ses, false);
         if (status)
@@ -5260,6 +5270,7 @@
         hw_ses->fptrs->stop_buffering(hw_ses);
         if (hw_ses->sthw_cfg_updated || ev->ev_id == ST_SES_EV_START) {
             status = stop_session(st_ses, hw_ses, false);
+            STATE_TRANSITION(st_ses, loaded_state_fn);
             if (status) {
                 ALOGE("%s:[%d] failed to stop session, err %d", __func__,
                     st_ses->sm_handle, status);