hal: Add support for audio feature manager

Fetch feature flags from audio config store.
Provide an interface for audio_extn, platform
and hal code to check if a feature is enabled
or disabled at runtime.

Change-Id: I35d873c787258aee75481de343fcbcbc51cb9e91
diff --git a/hal/Android.mk b/hal/Android.mk
index a67ce7c..c39900e 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -102,7 +102,8 @@
 	voice.c \
 	platform_info.c \
 	$(AUDIO_PLATFORM)/platform.c \
-        acdb.c
+        acdb.c \
+        ahal_config_helper.cpp
 
 LOCAL_SRC_FILES += audio_extn/audio_extn.c \
                    audio_extn/audio_feature_manager.c \
@@ -343,13 +344,15 @@
     libaudioroute \
     libdl \
     libaudioutils \
-    libexpat
+    libexpat \
+    libqti_vndfwk_detect
 
 LOCAL_C_INCLUDES += \
     external/tinyalsa/include \
     external/tinycompress/include \
     system/media/audio_utils/include \
     external/expat/lib \
+    vendor/qcom/opensource/core-utils/fwk-detect \
     $(call include-path-for, audio-route) \
     $(call include-path-for, audio-effects) \
     $(LOCAL_PATH)/$(AUDIO_PLATFORM) \
diff --git a/hal/ahal_config_helper.cpp b/hal/ahal_config_helper.cpp
new file mode 100644
index 0000000..92bb520
--- /dev/null
+++ b/hal/ahal_config_helper.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2019, 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ahal_config_helper"
+
+#include "ahal_config_helper.h"
+#include <cutils/properties.h>
+#include <log/log.h>
+
+struct AHalConfigHelper {
+    static AHalConfigHelper* mConfigHelper;
+
+    AHalConfigHelper() : isRemote(false) { };
+    static AHalConfigHelper* getAHalConfInstance() {
+        if (!mConfigHelper)
+            mConfigHelper = new AHalConfigHelper();
+        return mConfigHelper;
+    }
+    void initDefaultConfig(bool isVendorEnhancedFwk);
+    AHalValues* getAHalValues();
+    inline void retrieveConfigs();
+
+    AHalValues mConfigs;
+    bool isRemote; // configs specified from remote
+};
+
+AHalConfigHelper* AHalConfigHelper::mConfigHelper;
+
+void AHalConfigHelper::initDefaultConfig(bool isVendorEnhancedFwk)
+{
+    ALOGV("%s: enter", __FUNCTION__);
+    if (isVendorEnhancedFwk) {
+        mConfigs = {
+            true,        /* SND_MONITOR */
+            false,       /* COMPRESS_CAPTURE */
+            true,        /* SOURCE_TRACK */
+            true,        /* SSREC */
+            true,        /* AUDIOSPHERE */
+            true,        /* AFE_PROXY */
+            false,       /* USE_DEEP_AS_PRIMARY_OUTPUT */
+            true,        /* HDMI_EDID */
+            true,        /* KEEP_ALIVE */
+            false,       /* HIFI_AUDIO */
+            true,        /* RECEIVER_AIDED_STEREO */
+            true,        /* KPI_OPTIMIZE */
+            true,        /* DISPLAY_PORT */
+            true,        /* FLUENCE */
+            true,        /* CUSTOM_STEREO */
+            true,        /* ANC_HEADSET */
+            false,       /* DSM_FEEDBACK */
+            true,        /* USB_OFFLOAD */
+            false,       /* USB_OFFLOAD_BURST_MODE */
+            false,       /* USB_OFFLOAD_SIDETONE_VOLM */
+            true,        /* A2DP_OFFLOAD */
+            true,        /* VBAT */
+            true,        /* COMPRESS_METADATA_NEEDED */
+            false,       /* COMPRESS_VOIP */
+            false,       /* DYNAMIC_ECNS */
+        };
+    } else {
+        mConfigs = {
+            true,        /* SND_MONITOR */
+            false,       /* COMPRESS_CAPTURE */
+            false,       /* SOURCE_TRACK */
+            false,       /* SSREC */
+            false,       /* AUDIOSPHERE */
+            false,       /* AFE_PROXY */
+            false,       /* USE_DEEP_AS_PRIMARY_OUTPUT */
+            false,       /* HDMI_EDID */
+            false,       /* KEEP_ALIVE */
+            false,       /* HIFI_AUDIO */
+            false,       /* RECEIVER_AIDED_STEREO */
+            false,       /* KPI_OPTIMIZE */
+            false,       /* DISPLAY_PORT */
+            false,       /* FLUENCE */
+            false,       /* CUSTOM_STEREO */
+            false,       /* ANC_HEADSET */
+            false,       /* DSM_FEEDBACK */
+            true,        /* USB_OFFLOAD */
+            false,       /* USB_OFFLOAD_BURST_MODE */
+            false,       /* USB_OFFLOAD_SIDETONE_VOLM */
+            true,        /* A2DP_OFFLOAD */
+            false,       /* VBAT */
+            false,       /* COMPRESS_METADATA_NEEDED */
+            false,       /* COMPRESS_VOIP */
+            false,       /* DYNAMIC_ECNS */
+        };
+    }
+}
+
+AHalValues* AHalConfigHelper::getAHalValues()
+{
+    ALOGV("%s: enter", __FUNCTION__);
+    retrieveConfigs();
+    return &mConfigs;
+}
+
+void AHalConfigHelper::retrieveConfigs()
+{
+    ALOGV("%s: enter", __FUNCTION__);
+    // ToDo: Add logic to query AHalValues from config store
+    // once support is added to it
+    return;
+}
+
+extern "C" {
+
+AHalValues* confValues = nullptr;
+
+void audio_extn_ahal_config_helper_init(bool is_vendor_enhanced_fwk)
+{
+    AHalConfigHelper* confInstance = AHalConfigHelper::getAHalConfInstance();
+    if (confInstance)
+        confInstance->initDefaultConfig(is_vendor_enhanced_fwk);
+}
+
+AHalValues* audio_extn_get_feature_values()
+{
+    AHalConfigHelper* confInstance = AHalConfigHelper::getAHalConfInstance();
+    if (confInstance)
+        confValues = confInstance->getAHalValues();
+    return confValues;
+}
+
+bool audio_extn_is_config_from_remote()
+{
+    AHalConfigHelper* confInstance = AHalConfigHelper::getAHalConfInstance();
+    if (confInstance)
+        return confInstance->isRemote;
+    return false;
+}
+
+} // extern C
diff --git a/hal/ahal_config_helper.h b/hal/ahal_config_helper.h
new file mode 100644
index 0000000..6e19bfa
--- /dev/null
+++ b/hal/ahal_config_helper.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// ToDo: This struct must be used only if config store is disabled.
+// Use AHalValues struct from config store once support is added.
+struct AHalValues_t {
+    bool snd_monitor_enabled;
+    bool compress_capture_enabled;
+    bool source_track_enabled;
+    bool ssrec_enabled;
+    bool audiosphere_enabled;
+    bool afe_proxy_enabled;
+    bool use_deep_buffer_as_primary_output;
+    bool hdmi_edid_enabled;
+    bool keep_alive_enabled;
+    bool hifi_audio_enabled;
+    bool receiver_aided_stereo;
+    bool kpi_optimize_enabled;
+    bool display_port_enabled;
+    bool fluence_enabled;
+    bool custom_stereo_enabled;
+    bool anc_headset_enabled;
+    bool dsm_feedback_enabled;
+    bool usb_offload_enabled;
+    bool usb_offload_burst_mode;
+    bool usb_offload_sidetone_vol_enabled;
+    bool a2dp_offload_enabled;
+    bool vbat_enabled;
+    bool compress_metadata_needed;
+    bool compress_voip_enabled;
+    bool dynamic_ecns_enabled;
+};
+typedef struct AHalValues_t AHalValues;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void audio_extn_ahal_config_helper_init(bool isVendorEnhancedFwk);
+AHalValues* audio_extn_get_feature_values();
+bool audio_extn_is_config_from_remote();
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/hal/audio_extn/audio_feature_manager.c b/hal/audio_extn/audio_feature_manager.c
index a399800..23de0eb 100644
--- a/hal/audio_extn/audio_feature_manager.c
+++ b/hal/audio_extn/audio_feature_manager.c
@@ -27,9 +27,8 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+//#define LOG_NDEBUG 0
 #define LOG_TAG "audio_feature_manager"
-/*#define LOG_NDEBUG 0*/
-#define LOG_NDDEBUG 0
 
 #include <stdlib.h>
 #include <errno.h>
@@ -37,37 +36,83 @@
 #include <cutils/properties.h>
 #include <log/log.h>
 #include <unistd.h>
+#include <vndfwk-detect.h>
 #include "audio_feature_manager.h"
-#include <cutils/str_parms.h>
 
-static bool feature_bit_map[MAX_SUPPORTED_FEATURE] = {0};
+extern AHalValues* confValues;
 
-static void set_default_feature_flags() {
-    ALOGI(":: %s: Enter", __func__);
-    feature_bit_map[SND_MONITOR] = true;
+void audio_feature_manager_init()
+{
+    ALOGV("%s: Enter", __func__);
+    audio_extn_ahal_config_helper_init(
+                isRunningWithVendorEnhancedFramework());
+    confValues = audio_extn_get_feature_values();
 }
 
-static void set_dynamic_feature_flags() {
-    ALOGI(":: %s: Enter", __func__);
-    // TBD: Dynamically init feature bit
-}
+bool audio_feature_manager_is_feature_enabled(audio_ext_feature feature)
+{
+    ALOGV("%s: Enter", __func__);
 
-static void set_feature_flags() {
-    ALOGI(":: %s: Enter", __func__);
-    set_default_feature_flags();
-    set_dynamic_feature_flags();
-}
+#ifdef AHAL_EXT_ENABLED
+    if (!audio_extn_is_config_from_remote())
+        confValues = audio_extn_get_feature_values();
+#endif /* AHAL_EXT_ENABLED */
 
-void audio_feature_manager_init() {
-    ALOGI(":: %s: Enter", __func__);
-    set_feature_flags();
-}
+    if (!confValues)
+        return false;
 
-bool audio_feature_manager_is_feature_enabled(audio_ext_feature feature) {
-    bool ret_val = false;
-
-    if (feature >= 0 && feature < MAX_SUPPORTED_FEATURE)
-        ret_val = feature_bit_map[feature];
-
-    return ret_val;
+    switch (feature) {
+        case SND_MONITOR:
+            return confValues->snd_monitor_enabled;
+        case COMPRESS_CAPTURE:
+            return confValues->compress_capture_enabled;
+        case SOURCE_TRACK:
+            return confValues->source_track_enabled;
+        case SSREC:
+            return confValues->ssrec_enabled;
+        case AUDIOSPHERE:
+            return confValues->audiosphere_enabled;
+        case AFE_PROXY:
+            return confValues->afe_proxy_enabled;
+        case USE_DEEP_BUFFER_AS_PRIMARY_OUTPUT:
+            return confValues->use_deep_buffer_as_primary_output;
+        case HDMI_EDID:
+            return confValues->hdmi_edid_enabled;
+        case KEEP_ALIVE:
+            return confValues->keep_alive_enabled;
+        case HIFI_AUDIO:
+            return confValues->hifi_audio_enabled;
+        case RECEIVER_AIDED_STEREO:
+            return confValues->receiver_aided_stereo;
+        case KPI_OPTIMIZE:
+            return confValues->kpi_optimize_enabled;
+        case DISPLAY_PORT:
+            return confValues->display_port_enabled;
+        case FLUENCE:
+            return confValues->fluence_enabled;
+        case CUSTOM_STEREO:
+            return confValues->custom_stereo_enabled;
+        case ANC_HEADSET:
+            return confValues->anc_headset_enabled;
+        case DSM_FEEDBACK:
+            return confValues->dsm_feedback_enabled;
+        case USB_OFFLOAD:
+            return confValues->usb_offload_enabled;
+        case USB_OFFLOAD_BURST_MODE:
+            return confValues->usb_offload_burst_mode;
+        case USB_OFFLOAD_SIDETONE_VOLM:
+            return confValues->usb_offload_sidetone_vol_enabled;
+        case A2DP_OFFLOAD:
+            return confValues->a2dp_offload_enabled;
+        case VBAT:
+            return confValues->vbat_enabled;
+        case COMPRESS_METADATA_NEEDED:
+            return confValues->compress_metadata_needed;
+        case COMPRESS_VOIP:
+            return confValues->compress_voip_enabled;
+        case DYNAMIC_ECNS:
+            return confValues->dynamic_ecns_enabled;
+        default:
+            return false;
+    }
 }
diff --git a/hal/audio_extn/audio_feature_manager.h b/hal/audio_extn/audio_feature_manager.h
index 424dc4f..8433db0 100644
--- a/hal/audio_extn/audio_feature_manager.h
+++ b/hal/audio_extn/audio_feature_manager.h
@@ -30,8 +30,7 @@
 #ifndef AUDIO_FEATURE_MANAGER_H
 #define AUDIO_FEATURE_MANAGER_H
 
-#include <cutils/str_parms.h>
-
+#include <ahal_config_helper.h>
 
 enum audio_ext_feature_t {
     SND_MONITOR = 0,
@@ -40,7 +39,7 @@
     SSREC,
     AUDIOSPHERE,
     AFE_PROXY,
-    USE_DEEP_AS_PRIMARY_OUTPUT,
+    USE_DEEP_BUFFER_AS_PRIMARY_OUTPUT,
     HDMI_EDID,
     KEEP_ALIVE,
     HIFI_AUDIO,
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 37c749b..e12de67 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -6303,7 +6303,7 @@
                       (devices != AUDIO_DEVICE_OUT_USB_ACCESSORY);
     bool direct_dev = is_hdmi || is_usb_dev;
     bool use_db_as_primary =
-                audio_feature_manager_is_feature_enabled(USE_DEEP_AS_PRIMARY_OUTPUT);
+                audio_feature_manager_is_feature_enabled(USE_DEEP_BUFFER_AS_PRIMARY_OUTPUT);
 
     if (is_usb_dev && (!audio_extn_usb_connected(NULL))) {
         is_usb_dev = false;
@@ -8434,6 +8434,8 @@
     adev->bt_sco_on = false;
     /* adev->cur_hdmi_channels = 0;  by calloc() */
     adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
+    /* Init audio feature manager */
+    audio_feature_manager_init();
     voice_init(adev);
     list_init(&adev->usecase_list);
     adev->cur_wfd_channels = 2;
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 86bbf98..f75ffe1 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -79,6 +79,7 @@
 
 LOCAL_C_INCLUDES := \
         external/tinyalsa/include \
+        vendor/qcom/opensource/audio-hal/primary-hal/hal \
         $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
 	$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include \
         $(call include-path-for, audio-effects) \