Merge 59145161212ff5c9b71b9830fe1201f56a36cb4a on remote branch

Change-Id: I7d6cede4d67bd7413e1a48d13a11089b2ed43d59
diff --git a/configs/audio_vendor_product.mk b/configs/audio_vendor_product.mk
index 0857817..c68e42e 100644
--- a/configs/audio_vendor_product.mk
+++ b/configs/audio_vendor_product.mk
@@ -201,7 +201,7 @@
 # audio specific
 # ------
 TARGET_USES_AOSP := true
-TARGET_USES_AOSP_FOR_AUDIO := true
+TARGET_USES_AOSP_FOR_AUDIO := false
 
 # sdm845 specific rules
 ifeq ($(TARGET_BOARD_PLATFORM),sdm845)
diff --git a/configs/msmnile_au/msmnile_au.mk b/configs/msmnile_au/msmnile_au.mk
old mode 100755
new mode 100644
index 6a3a9f4..12d9b15
--- a/configs/msmnile_au/msmnile_au.mk
+++ b/configs/msmnile_au/msmnile_au.mk
@@ -16,7 +16,7 @@
 else
 USE_CUSTOM_AUDIO_POLICY := 0
 endif
-AUDIO_FEATURE_QSSI_COMPLIANCE := true
+AUDIO_FEATURE_QSSI_COMPLIANCE := false
 AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
 AUDIO_FEATURE_ENABLED_COMPRESS_INPUT := true
 AUDIO_FEATURE_ENABLED_CONCURRENT_CAPTURE := true
@@ -88,7 +88,6 @@
 AUDIO_FEATURE_ENABLED_GEF_SUPPORT := true
 BOARD_SUPPORTS_QAHW := false
 AUDIO_FEATURE_ENABLED_RAS := true
-AUDIO_FEATURE_ENABLED_SND_MONITOR := false
 AUDIO_FEATURE_ENABLED_DLKM := true
 AUDIO_FEATURE_ENABLED_USB_BURST_MODE := false
 AUDIO_FEATURE_ENABLED_SVA_MULTI_STAGE := true
@@ -96,7 +95,9 @@
 AUDIO_FEATURE_ENABLED_SOFT_VOLUME:= true
 ##AUDIO_FEATURE_FLAGS
 
+ifneq ($(ENABLE_AUDIO_LEGACY_TECHPACK),true)
 AUDIO_HARDWARE += audio.a2dp.default
+endif
 AUDIO_HARDWARE += audio.usb.default
 AUDIO_HARDWARE += audio.r_submix.default
 AUDIO_HARDWARE += audio.primary.msmnile
@@ -126,12 +127,18 @@
 AUDIO_FEATURE_ENABLED_DAEMON_SUPPORT := false
 AUDIO_FEATURE_ENABLED_SILENT_BOOT := false
 endif
+AUDIO_FEATURE_ENABLED_SND_MONITOR := false
+else
+AUDIO_FEATURE_ENABLED_SND_MONITOR := true
 endif
 AUDIO_FEATURE_ENABLED_FM_TUNER_EXT := true
 AUDIO_FEATURE_ENABLED_ICC := true
 ifneq ( ,$(filter S 12, $(PLATFORM_VERSION)))
 AUDIO_FEATURE_ENABLED_POWER_POLICY := true
 endif
+ifeq ($(TARGET_BOARD_PLATFORM)$(TARGET_BOARD_SUFFIX), msmnile_gvmq)
+AUDIO_FEATURE_ENABLED_AUDIO_PARSERS := true
+endif
 ##AUTOMOTIVE_AUDIO_FEATURE_FLAGS
 
 ifneq ($(strip $(TARGET_USES_RRO)), true)
@@ -422,11 +429,17 @@
 vendor.audio.feature.vbat.enable=false \
 vendor.audio.feature.wsa.enable=false \
 vendor.audio.feature.audiozoom.enable=false \
-vendor.audio.feature.snd_mon.enable=false \
 vendor.audio.feature.auto_hal.enable=true \
 vendor.audio.feature.synth.enable=true \
 vendor.audio.feature.powerpolicy.enable=true \
 vendor.audio.feature.concurrent_pcm_record.enable=true
+ifeq ($(AUDIO_FEATURE_ENABLED_SND_MONITOR), true)
+PRODUCT_ODM_PROPERTIES += \
+vendor.audio.feature.snd_mon.enable=true
+else
+PRODUCT_ODM_PROPERTIES += \
+vendor.audio.feature.snd_mon.enable=false
+endif
 else
 # Non-Generic ODM varient related
 PRODUCT_ODM_PROPERTIES += \
@@ -471,11 +484,17 @@
 vendor.audio.feature.vbat.enable=true \
 vendor.audio.feature.wsa.enable=false \
 vendor.audio.feature.audiozoom.enable=false \
-vendor.audio.feature.snd_mon.enable=false \
 vendor.audio.feature.auto_hal.enable=true \
 vendor.audio.feature.synth.enable=true \
 vendor.audio.feature.powerpolicy.enable=true \
 vendor.audio.feature.concurrent_pcm_record.enable=true
+ifeq ($(AUDIO_FEATURE_ENABLED_SND_MONITOR), true)
+PRODUCT_ODM_PROPERTIES += \
+vendor.audio.feature.snd_mon.enable=true
+else
+PRODUCT_ODM_PROPERTIES += \
+vendor.audio.feature.snd_mon.enable=false
+endif
 endif
 
 # for HIDL related packages
diff --git a/configure.ac b/configure.ac
index 2103efd..d2692c7 100755
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,14 @@
                [TARGET_SUPPORT=none]
 )
 
+AC_ARG_WITH(hal-path,
+        AS_HELP_STRING([--with-hal-path=DIR], [Specify the HAL modules location in run time]),
+        [HAL_PATH="$withval"],
+        [HAL_PATH="no"])
+
+AM_CONDITIONAL([HAL_PATH_SPECIFIED], [test "x${HAL_PATH}" != "xno"])
+AC_SUBST(HAL_PATH)
+
 if (test "x${with_glib}" = "xyes"); then
         PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
                                 AC_MSG_ERROR(GThread >= 2.16 is required))
diff --git a/hal/Makefile.am b/hal/Makefile.am
index f14ab4c..79b5dea 100755
--- a/hal/Makefile.am
+++ b/hal/Makefile.am
@@ -192,6 +192,9 @@
 AM_CFLAGS += -DAUDIO_DISABLE_COMPRESS_FORMAT
 endif
 
+if HAL_PATH_SPECIFIED
+AM_CFLAGS += -DHAL_LIBRARY_PATH=\"@HAL_PATH@\"
+endif
 h_sources = audio_extn/audio_defs.h \
             audio_extn/audio_extn.h \
             audio_hw.h \
@@ -209,6 +212,9 @@
 audio_primary_default_la_LIBADD += -laudioparsers
 endif
 audio_primary_default_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
+if HAL_PATH_SPECIFIED
+audio_primary_default_la_CFLAGS += -DHAL_LIBRARY_PATH=\"@HAL_PATH@\"
+endif
 audio_primary_default_la_CFLAGS += -Dstrlcat=g_strlcat
 audio_primary_default_la_CFLAGS += -DINT_MAX=0x7fffffff -Wno-error=deprecated-declarations -DPATH_MAX=1024 -DULONG_MAX=0xFFFFFFFFFFFFFFFFUL
 audio_primary_default_la_CFLAGS += -D__unused=__attribute__\(\(__unused__\)\)
diff --git a/hal/audio_extn/Makefile.am b/hal/audio_extn/Makefile.am
index 3bc20b0..5f55dc6 100755
--- a/hal/audio_extn/Makefile.am
+++ b/hal/audio_extn/Makefile.am
@@ -221,6 +221,10 @@
 libhfp_la_LIBADD += -ltinycompress -laudioroute -ldl -lexpat -laudioutils
 libhfp_la_LIBADD += -lm -lc -lresolv
 
+if AUDIO_PARSER
+libhfp_la_LIBADD += -laudioparsers
+endif
+
 libhfp_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
 libhfp_la_CFLAGS += -Dstrlcat=g_strlcat
 libhfp_la_CFLAGS += -DINT_MAX=0x7fffffff
@@ -230,6 +234,9 @@
 libhfp_la_CFLAGS += -DLINUX_ENABLED $(TARGET_CFLAGS) -DAUDIO_EXTN_FORMATS_ENABLED
 libhfp_la_CFLAGS += -DNDEBUG
 libhfp_la_CFLAGS += -D_GNU_SOURCE
+if HAL_PATH_SPECIFIED
+libhfp_la_CFLAGS += -DHAL_LIBRARY_PATH=\"@HAL_PATH@\"
+endif
 libhfp_la_LDFLAGS = -module -shared -avoid-version
 endif
 
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 95fd487..81fdcc3 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -4935,14 +4935,24 @@
 #ifdef __LP64__
 #ifdef LINUX_ENABLED
 #define HFP_LIB_PATH "/usr/lib64/libhfp.so"
+#define LINUX_PATH true
+#ifdef HAL_LIBRARY_PATH
+#define HFP_LIB_PATH HAL_LIBRARY_PATH
+#endif
 #else
 #define HFP_LIB_PATH "/vendor/lib64/libhfp.so"
+#define LINUX_PATH false
 #endif
 #else
 #ifdef LINUX_ENABLED
 #define HFP_LIB_PATH "/usr/lib/libhfp.so"
+#define LINUX_PATH true
+#ifdef HAL_LIBRARY_PATH
+#define HFP_LIB_PATH HAL_LIBRARY_PATH
+#endif
 #else
 #define HFP_LIB_PATH "/vendor/lib/libhfp.so"
+#define LINUX_PATH false
 #endif
 #endif
 
@@ -4973,8 +4983,12 @@
                   is_feature_enabled ? "Enabled" : "NOT Enabled");
     if (is_feature_enabled) {
         // dlopen lib
-        hfp_lib_handle = dlopen(HFP_LIB_PATH, RTLD_NOW);
-
+        if (LINUX_PATH) {
+            char libhfp_path[100];
+            snprintf(libhfp_path, sizeof(libhfp_path), "%s/libhfp.so", HFP_LIB_PATH);
+            hfp_lib_handle = dlopen(libhfp_path, RTLD_NOW);
+        } else
+            hfp_lib_handle = dlopen(HFP_LIB_PATH , RTLD_NOW);
         if (!hfp_lib_handle) {
             ALOGE("%s: dlopen failed", __func__);
             goto feature_disabled;
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index 2948402..386bfc1 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -236,6 +236,7 @@
     }
 
 exit:
+    clear_devices(&out_devices);
     pthread_mutex_unlock(&ka.lock);
 }
 
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index d7c4b03..5d573d0 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -587,6 +587,7 @@
                                   __func__, event, snd_device);
         }
     }/*Events for output device, if required can be placed here in else*/
+    clear_devices(&ev_info.device_info.devices);
 }
 
 void audio_extn_sound_trigger_update_stream_status(struct audio_usecase *uc_info,
@@ -645,6 +646,7 @@
             }
         }
     }
+    clear_devices(&ev_info.device_info.devices);
 }
 
 void audio_extn_sound_trigger_update_battery_status(bool charging)
@@ -874,6 +876,7 @@
     if (st_dev && (st_dev->adev == adev) && st_dev->lib_handle) {
         audio_extn_snd_mon_unregister_listener(st_dev);
         dlclose(st_dev->lib_handle);
+        clear_devices(&st_dev->st_ses_list);
         free(st_dev);
         st_dev = NULL;
     }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
old mode 100755
new mode 100644
index 7684f21..ef6bc40
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -712,8 +712,8 @@
     if (!adev->adm_set_config)
         return;
 
-    if (out->realtime)
-        adev->adm_set_config(adev->adm_data,
+    if (out->realtime || (out->flags & AUDIO_OUTPUT_FLAG_SYS_NOTIFICATION))
+       adev->adm_set_config(adev->adm_data,
                              out->handle,
                              out->pcm, &out->config);
 }
@@ -1398,6 +1398,7 @@
 
                 platform_set_echo_reference(adev, true, &out_devices);
                 in->ec_opened = true;
+                clear_devices(&out_devices);
             }
         }
     } else if ((usecase->type == TRANSCODE_LOOPBACK_TX) || ((usecase->type == PCM_HFP_CALL) &&
@@ -1524,6 +1525,7 @@
             list_init(&out_devices);
             platform_set_echo_reference(in->dev, false, &out_devices);
             in->ec_opened = false;
+            clear_devices(&out_devices);
         }
     }
     if (usecase->id == adev->fluence_nn_usecase_id) {
@@ -1933,6 +1935,9 @@
         }
     }
 
+    clear_devices(&a1);
+    clear_devices(&a2);
+
 end:
     return d2; // return whatever was calculated before.
 }
@@ -2923,6 +2928,7 @@
         out_snd_device = platform_get_output_snd_device(adev->platform, &stream_out, usecase->type);
         assign_devices(&usecase->device_list,
                        &usecase->stream.inout->out_config.device_list);
+        clear_devices(&stream_out.device_list);
     } else if (usecase->type == TRANSCODE_LOOPBACK_TX ) {
         if (usecase->stream.inout == NULL) {
             ALOGE("%s: stream.inout is NULL", __func__);
@@ -2934,6 +2940,7 @@
                                                       &out_devices, usecase->type);
         assign_devices(&usecase->device_list,
                        &usecase->stream.inout->in_config.device_list);
+        clear_devices(&out_devices);
     } else {
         /*
          * If the voice call is active, use the sound devices of voice call usecase
@@ -3073,6 +3080,7 @@
                                                                   priority_in,
                                                                   &out_devices,
                                                                   usecase->type);
+                clear_devices(&out_devices);
             }
         }
     }
@@ -3405,6 +3413,7 @@
         audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_PRIMARY);
 
     list_remove(&uc_info->list);
+    clear_devices(&uc_info->device_list);
     free(uc_info);
 
     if (priority_in == in) {
@@ -3589,7 +3598,8 @@
             in->pcm = NULL;
             goto error_open;
         }
-        register_in_stream(in);
+        if (in->flags == AUDIO_INPUT_FLAG_FAST)
+            register_in_stream(in);
         if (in->realtime) {
             ATRACE_BEGIN("pcm_in_start");
             ret = pcm_start(in->pcm);
@@ -4056,6 +4066,7 @@
         }
     }
 
+    clear_devices(&uc_info->device_list);
     free(uc_info);
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
@@ -4240,6 +4251,7 @@
                                 AUDIO_DEVICE_OUT_SPEAKER, "");
             select_devices(adev, out->usecase);
             assign_devices(&out->device_list, &dev);
+            clear_devices(&dev);
         }
     } else {
         select_devices(adev, out->usecase);
@@ -4257,6 +4269,7 @@
                                     AUDIO_DEVICE_OUT_SPEAKER, "");
                 select_devices(adev, out->usecase);
                 assign_devices(&out->device_list, &dev);
+                clear_devices(&dev);
             } else {
                 ret = -EINVAL;
                 goto error_open;
@@ -4445,7 +4458,8 @@
     }
 
     if (ret == 0) {
-        register_out_stream(out);
+        if (out->flags == AUDIO_OUTPUT_FLAG_FAST)
+            register_out_stream(out);
         if (out->realtime) {
             if (out->pcm == NULL || !pcm_is_ready(out->pcm)) {
                 ALOGE("%s: pcm stream not ready", __func__);
@@ -5766,16 +5780,28 @@
         ret = platform_get_soft_step_volume_params(volume_params,out->usecase);
         if (ret < 0) {
             ALOGE("%s : platform_get_soft_step_volume_params is fialed", __func__);
-            return -EINVAL;
+            ret = -EINVAL;
+            goto ERR_EXIT;
         }
 
     }
     ret = mixer_ctl_set_array(ctl, volume_params, sizeof(struct soft_step_volume_params)/sizeof(int));
     if (ret < 0) {
         ALOGE("%s: Could not set ctl, error:%d ", __func__, ret);
-        return -EINVAL;
+        ret = -EINVAL;
+        goto ERR_EXIT;
+    }
+
+    if (volume_params) {
+        free(volume_params);
     }
     return 0;
+
+ERR_EXIT:
+    if (volume_params) {
+        free(volume_params);
+    }
+    return ret;
 }
 #endif
 
@@ -8046,6 +8072,7 @@
         }
     }
 
+    clear_devices(&devices);
     pthread_mutex_unlock(&adev->lock);
     pthread_mutex_unlock(&in->lock);
 }
@@ -9033,6 +9060,7 @@
     pthread_mutex_destroy(&out->position_query_lock);
 
     pthread_mutex_lock(&adev->lock);
+    clear_devices(&out->device_list);
     free(stream);
     pthread_mutex_unlock(&adev->lock);
     ALOGV("%s: exit", __func__);
@@ -10001,7 +10029,26 @@
         in->config.rate = config->sample_rate;
         in->af_period_multiplier = 1;
     } else if (in->realtime) {
-        in->config = pcm_config_audio_capture_rt;
+        switch(config->sample_rate)
+        {
+            case 48000:
+                in->config = pcm_config_audio_capture_rt_48KHz;
+                break;
+            case 32000:
+                in->config = pcm_config_audio_capture_rt_32KHz;
+                break;
+            case 24000:
+                in->config = pcm_config_audio_capture_rt_24KHz;
+                break;
+            case 16000:
+                in->config = pcm_config_audio_capture_rt_16KHz;
+                break;
+            case 8000:
+                in->config = pcm_config_audio_capture_rt_8KHz;
+                break;
+            default:
+                in->config = pcm_config_audio_capture_rt_48KHz;
+        }
         in->config.format = pcm_format_from_audio_format(config->format);
         in->af_period_multiplier = af_period_multiplier;
     } else {
@@ -10090,30 +10137,6 @@
             }
         }
     }
-    if (in->realtime) {
-        switch(config->sample_rate)
-        {
-            case 48000:
-                in->config = pcm_config_audio_capture_rt_48KHz;
-                break;
-            case 32000:
-                in->config = pcm_config_audio_capture_rt_32KHz;
-                break;
-            case 24000:
-                in->config = pcm_config_audio_capture_rt_24KHz;
-                break;
-            case 16000:
-                in->config = pcm_config_audio_capture_rt_16KHz;
-                break;
-            case 8000:
-                in->config = pcm_config_audio_capture_rt_8KHz;
-                break;
-            default:
-                in->config = pcm_config_audio_capture_rt_48KHz;
-        }
-        in->config.format = pcm_format_from_audio_format(config->format);
-        in->af_period_multiplier = af_period_multiplier;
-    }
 
     if (audio_extn_ssr_get_stream() != in)
         in->config.channels = channel_count;
@@ -10212,6 +10235,7 @@
         struct listnode out_devices;
         list_init(&out_devices);
         platform_set_echo_reference(adev, false, &out_devices);
+        clear_devices(&out_devices);
     } else
         audio_extn_sound_trigger_update_ec_ref_status(false);
 
@@ -10263,6 +10287,7 @@
         ALOGV("%s: sound trigger pcm stop lab", __func__);
         audio_extn_sound_trigger_stop_lab(in);
     }
+    clear_devices(&in->device_list);
     free(stream);
     pthread_mutex_unlock(&adev->lock);
     return;
@@ -10575,7 +10600,6 @@
     if (stream != NULL) {
         if (p_info->patch_type == PATCH_PLAYBACK) {
             ret = route_output_stream((struct stream_out *) stream, &devices);
-            clear_devices(&devices);
         } else if (p_info->patch_type == PATCH_CAPTURE) {
             ret = route_input_stream((struct stream_in *) stream, &devices, input_source);
         }
@@ -10599,6 +10623,7 @@
     }
 
 done:
+    clear_devices(&devices);
     audio_extn_hw_loopback_create_audio_patch(dev,
                                         num_sources,
                                         sources,
@@ -10684,6 +10709,7 @@
             ret = route_output_stream((struct stream_out *) stream, &devices);
         else if (patch_type == PATCH_CAPTURE)
             ret = route_input_stream((struct stream_in *) stream, &devices, input_source);
+        clear_devices(&devices);
     }
 
     if (ret < 0)
@@ -10921,6 +10947,7 @@
         }
         pthread_mutex_unlock(&out->latch_lock);
     }
+    clear_devices(&devices);
     ALOGV("%s: exit", __func__);
     return 0;
 }
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 9638643..59c3c8f 100755
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -6940,6 +6940,7 @@
         ALOGE("%s: Unknown device(s) %#x", __func__, get_device_types(&devices));
     }
 exit:
+    clear_devices(&devices);
     ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
     return snd_device;
 }
@@ -7784,6 +7785,7 @@
         }
     }
 exit:
+    clear_devices(&in_devices);
     ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
     return snd_device;
 }
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 4d09144..25ebc08 100755
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -703,6 +703,11 @@
 #define HFP_ASM_RX_TX 18
 #define HFP_SEC_SCO_RX -1
 #define HFP_SEC_ASM_RX_TX -1
+#elif PLATFORM_MSMSTEPPE
+#define HFP_SCO_RX 12
+#define HFP_ASM_RX_TX 37
+#define HFP_SEC_SCO_RX -1
+#define HFP_SEC_ASM_RX_TX -1
 #else
 #define HFP_SCO_RX 23
 #define HFP_ASM_RX_TX 24