st-hal: restart session if buffering stopped early

In case of buffering stopped early which second
stage detection not get triggered, an internal
restart is needed to switch session to active
state, thus subsequent trigger events can be
handled properly.

Change-Id: I97a67b0805855bef0f5e9207c30ea0b7464c849a
diff --git a/st_session.c b/st_session.c
index 732125f..9da0518 100644
--- a/st_session.c
+++ b/st_session.c
@@ -4,7 +4,7 @@
  * user session. This state machine implements logic for handling all user
  * interactions, detectinos, SSR and Audio Concurencies.
  *
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -4807,18 +4807,34 @@
                  * Note: It is possible that detection event is not sent to
                  * client if second stage is not yet detected during internal
                  * buffering stop, in which case restart is posted from second
-                 * stage thread for further detections.
+                 * stage thread for further detections. Only if the second
+                 * stage detection hasn't be started due to internal buffering
+                 * stop too early, restart session should be explictily issued.
                  */
-                if ((st_ses->current_state == buffering_state_fn) &&
-                    !stc_ses->pending_stop && stc_ses->detection_sent) {
-                    ALOGD("%s:[%d] buffering stopped internally, post c%d stop",
-                        __func__, st_ses->sm_handle,
-                        st_ses->det_stc_ses->sm_handle);
-                    status = hw_session_notifier_enqueue(stc_ses->sm_handle,
-                        ST_SES_EV_DEFERRED_STOP,
-                        ST_SES_DEFERRED_STOP_SS_DELAY_MS);
-                    if (!status)
-                        stc_ses->pending_stop = true;
+                if (st_ses->current_state == buffering_state_fn) {
+                    if (stc_ses->detection_sent) {
+                        if (!stc_ses->pending_stop) {
+                            ALOGD("%s:[%d] buffering stopped internally, post c%d stop",
+                                __func__, st_ses->sm_handle,
+                                st_ses->det_stc_ses->sm_handle);
+                            status = hw_session_notifier_enqueue(stc_ses->sm_handle,
+                                ST_SES_EV_DEFERRED_STOP,
+                                ST_SES_DEFERRED_STOP_SS_DELAY_MS);
+                            if (!status)
+                                stc_ses->pending_stop = true;
+                        }
+                    } else {
+                        list_for_each(node, &stc_ses->second_stage_list) {
+                            st_sec_stage = node_to_item(node, st_arm_second_stage_t,
+                                                        list_node);
+                            if (!st_sec_stage->ss_session->start_processing) {
+                                st_session_ev_t ev = {.ev_id = ST_SES_EV_RESTART,
+                                                      .stc_ses = stc_ses};
+                                DISPATCH_EVENT(st_ses, ev, status);
+                                break;
+                            }
+                        }
+                    }
                 }
                 pthread_mutex_unlock(&st_ses->lock);
             }