hal: Add/remove speaker protection usecase to/from global list

Audio hal maintains link list that contains all active audio/voice
usecases. When usecase is being started it shoule be be added to
list and removed when usecase is disabled.
Speaker protection usecases were not being added to the list which was
causing the speaker calibration pre-emption to fail. Change updates the
usecase list and ensures that device lock is not acquired when
calibration is being pre-empted

CRs-fixed: 688972
Change-Id: I377346243ceaaebfcf80673f367dbd8bb83d5381
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index b1ad358..937b30d 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -164,7 +164,6 @@
             pthread_cond_wait(&handle.spkr_calibcancel_ack,
             &handle.spkr_calib_cancelack_mutex);
             pthread_mutex_unlock(&handle.spkr_calib_cancelack_mutex);
-            pthread_mutex_unlock(&handle.mutex_spkr_prot);
     }
     ALOGV("%s: Exit", __func__);
 }
@@ -303,6 +302,7 @@
     uc_info_rx->out_snd_device = SND_DEVICE_OUT_SPEAKER_PROTECTED;
     pthread_mutex_lock(&adev->lock);
     disable_rx = true;
+    list_add_tail(&adev->usecase_list, &uc_info_rx->list);
     enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
     enable_audio_route(adev, uc_info_rx);
     pthread_mutex_unlock(&adev->lock);
@@ -333,6 +333,7 @@
 
     pthread_mutex_lock(&adev->lock);
     disable_tx = true;
+    list_add_tail(&adev->usecase_list, &uc_info_tx->list);
     enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
     enable_audio_route(adev, uc_info_tx);
     pthread_mutex_unlock(&adev->lock);
@@ -410,16 +411,20 @@
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
         handle.pcm_tx = NULL;
-        pthread_mutex_lock(&adev->lock);
+        if (!handle.cancel_spkr_calib)
+            pthread_mutex_lock(&adev->lock);
         if (disable_rx) {
+            list_remove(&uc_info_rx->list);
             disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
             disable_audio_route(adev, uc_info_rx);
         }
         if (disable_tx) {
+            list_remove(&uc_info_tx->list);
             disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
             disable_audio_route(adev, uc_info_tx);
         }
-        pthread_mutex_unlock(&adev->lock);
+        if (!handle.cancel_spkr_calib)
+            pthread_mutex_unlock(&adev->lock);
 
         if (!status.status) {
             protCfg.mode = MSM_SPKR_PROT_CALIBRATED;
@@ -677,7 +682,7 @@
 
 int audio_extn_spkr_prot_start_processing(snd_device_t snd_device)
 {
-    struct audio_usecase uc_info_tx;
+    struct audio_usecase *uc_info_tx;
     struct audio_device *adev = handle.adev_handle;
     int32_t pcm_dev_tx_id = -1, ret = 0;
 
@@ -689,6 +694,7 @@
     }
     spkr_prot_calib_cancel(adev);
     spkr_prot_set_spkrstatus(true);
+    uc_info_tx = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
     ALOGV("%s: snd_device(%d: %s)", __func__, snd_device,
          platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_PROTECTED));
     audio_route_apply_and_update_path(adev->audio_route,
@@ -696,20 +702,19 @@
 
     pthread_mutex_lock(&handle.mutex_spkr_prot);
     if (handle.spkr_processing_state == SPKR_PROCESSING_IN_IDLE) {
-        memset(&uc_info_tx, 0 , sizeof(uc_info_tx));
-        uc_info_tx.id = USECASE_AUDIO_SPKR_CALIB_TX;
-        uc_info_tx.type = PCM_CAPTURE;
-        uc_info_tx.in_snd_device = SND_DEVICE_NONE;
-        uc_info_tx.out_snd_device = SND_DEVICE_NONE;
+        uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX;
+        uc_info_tx->type = PCM_CAPTURE;
+        uc_info_tx->in_snd_device = SND_DEVICE_NONE;
+        uc_info_tx->out_snd_device = SND_DEVICE_NONE;
         handle.pcm_tx = NULL;
-
+        list_add_tail(&adev->usecase_list, &uc_info_tx->list);
         enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
-        enable_audio_route(adev, &uc_info_tx);
+        enable_audio_route(adev, uc_info_tx);
 
-        pcm_dev_tx_id = platform_get_pcm_device_id(uc_info_tx.id, PCM_CAPTURE);
+        pcm_dev_tx_id = platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
         if (pcm_dev_tx_id < 0) {
             ALOGE("%s: Invalid pcm device for usecase (%d)",
-                  __func__, uc_info_tx.id);
+                  __func__, uc_info_tx->id);
             ret = -ENODEV;
             goto exit;
         }
@@ -736,8 +741,10 @@
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
         handle.pcm_tx = NULL;
+        list_remove(&uc_info_tx->list);
         disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
-        disable_audio_route(adev, &uc_info_tx);
+        disable_audio_route(adev, uc_info_tx);
+        free(uc_info_tx);
     } else
         handle.spkr_processing_state = SPKR_PROCESSING_IN_PROGRESS;
     pthread_mutex_unlock(&handle.mutex_spkr_prot);
@@ -747,22 +754,22 @@
 
 void audio_extn_spkr_prot_stop_processing()
 {
-    struct audio_usecase uc_info_tx;
+    struct audio_usecase *uc_info_tx;
     struct audio_device *adev = handle.adev_handle;
     ALOGV("%s: Entry", __func__);
     spkr_prot_set_spkrstatus(false);
     pthread_mutex_lock(&handle.mutex_spkr_prot);
     if (adev && handle.spkr_processing_state == SPKR_PROCESSING_IN_PROGRESS) {
-        memset(&uc_info_tx, 0 , sizeof(uc_info_tx));
-        uc_info_tx.id = USECASE_AUDIO_SPKR_CALIB_TX;
-        uc_info_tx.type = PCM_CAPTURE;
-        uc_info_tx.in_snd_device = SND_DEVICE_NONE;
-        uc_info_tx.out_snd_device = SND_DEVICE_NONE;
+        uc_info_tx = get_usecase_from_list(adev, USECASE_AUDIO_SPKR_CALIB_TX);
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
         handle.pcm_tx = NULL;
         disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
-        disable_audio_route(adev, &uc_info_tx);
+        if (uc_info_tx) {
+            list_remove(&uc_info_tx->list);
+            disable_audio_route(adev, uc_info_tx);
+            free(uc_info_tx);
+        }
     }
     handle.spkr_processing_state = SPKR_PROCESSING_IN_IDLE;
     pthread_mutex_unlock(&handle.mutex_spkr_prot);