hal: enable dynamic audio HAL feature extensions

Move audio and voice extension feature to seperate
dynamic libraries. Loading these libraries will be
controlled from config store based on target. These
flags can be changed at runtime

Change-Id: I042450768243124ea80945efac0821984f96b9bf
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index fcaf378..86bbf98 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -3,6 +3,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_CFLAGS := -DLIB_AUDIO_HAL="/vendor/lib/hw/audio.primary."$(TARGET_BOARD_PLATFORM)".so"
 LOCAL_CFLAGS += -Wno-unused-variable
 LOCAL_CFLAGS += -Wno-sign-compare
 LOCAL_CFLAGS += -Wno-unused-parameter
@@ -29,17 +30,13 @@
         virtualizer.c \
         reverb.c \
         effect_api.c \
-        effect_util.c
+        effect_util.c \
+        asphere.c
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS)),true)
-    LOCAL_CFLAGS += -DHW_ACCELERATED_EFFECTS
-    LOCAL_SRC_FILES += hw_accelerator.c
-endif
-
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUDIOSPHERE)),true)
-    LOCAL_CFLAGS += -DAUDIOSPHERE_ENABLED
-    LOCAL_SRC_FILES += asphere.c
-endif
+# HW_ACCELERATED has been disabled by default since msm8996. File doesn't
+# compile cleanly on tip so don't want to include it, but keeping this
+# as a reference.
+# LOCAL_SRC_FILES += hw_accelerator.c
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_INSTANCE_ID)), true)
     LOCAL_CFLAGS += -DINSTANCE_ID_ENABLED
@@ -84,7 +81,8 @@
         external/tinyalsa/include \
         $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
 	$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include \
-        $(call include-path-for, audio-effects)
+        $(call include-path-for, audio-effects) \
+        vendor/qcom/opensource/audio-hal/primary-hal/hal/audio_extn/
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
   LOCAL_HEADER_LIBRARIES += audio_kernel_headers
diff --git a/post_proc/Makefile.am b/post_proc/Makefile.am
index 54602a2..bd29473 100644
--- a/post_proc/Makefile.am
+++ b/post_proc/Makefile.am
@@ -20,7 +20,6 @@
 endif
 
 if AUDIOSPHERE
-AM_CFLAGS += -DAUDIOSPHERE_ENABLED
 c_sources += asphere.c
 endif
 
diff --git a/post_proc/asphere.c b/post_proc/asphere.c
index 54555d3..0ff55e5 100644
--- a/post_proc/asphere.c
+++ b/post_proc/asphere.c
@@ -33,6 +33,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <dlfcn.h>
 #include <stdbool.h>
 #include <sys/stat.h>
 #include <log/log.h>
@@ -41,6 +42,7 @@
 #include <cutils/properties.h>
 #include <hardware/audio_effect.h>
 #include <pthread.h>
+#include <audio_feature_manager.h>
 #include "bundle.h"
 #include "equalizer.h"
 #include "bass_boost.h"
@@ -56,6 +58,10 @@
 
 #define AUDIO_ASPHERE_EVENT_NODE "/data/misc/audio_pp/event_node"
 
+#define PRIMARY_HAL_PATH XSTR(LIB_AUDIO_HAL)
+#define XSTR(x) STR(x)
+#define STR(x) #x
+
 enum {
     ASPHERE_ACTIVE = 0,
     ASPHERE_SUSPENDED,
@@ -84,6 +90,7 @@
 
 static struct asphere_module asphere;
 pthread_once_t asphere_once = PTHREAD_ONCE_INIT;
+static bool (*is_feature_enabled)(audio_ext_feature);
 
 static int asphere_create_app_notification_node(void)
 {
@@ -162,9 +169,26 @@
 static void asphere_init_once() {
     ALOGD("%s", __func__);
     pthread_mutex_init(&asphere.lock, NULL);
-    asphere.init_status = 1;
-    asphere_get_values_from_mixer();
-    asphere_create_app_notification_node();
+
+    if (access(PRIMARY_HAL_PATH, R_OK) == 0) {
+        void *hal_lib_pointer = dlopen(PRIMARY_HAL_PATH, RTLD_NOW);
+        if (hal_lib_pointer == NULL)
+            ALOGE("%s: DLOPEN failed for %s", __func__, PRIMARY_HAL_PATH);
+        else if ((is_feature_enabled = (bool (*)(audio_ext_feature))dlsym(hal_lib_pointer,
+                                     "audio_feature_manager_is_feature_enable")) != NULL) {
+            if (is_feature_enabled(AUDIOSPHERE)) {
+                asphere.init_status = 1;
+                asphere_get_values_from_mixer();
+                asphere_create_app_notification_node();
+                return;
+            } else
+                ALOGW("%s: asphere feature not enabled", __func__);
+        } else
+            ALOGE("%s: dlsym failed", __func__);
+    } else
+        ALOGE("%s: not able to acces lib %s ", __func__, PRIMARY_HAL_PATH);
+
+    asphere.init_status = 0;
 }
 
 static int asphere_init() {
@@ -179,14 +203,8 @@
     bool enable = false;
     int strength = -1;
     char value[32] = {0};
-    char propValue[PROPERTY_VALUE_MAX] = {0};
     bool set_enable = false, set_strength = false;
 
-    if (!property_get("vendor.audio.pp.asphere.enabled", propValue, "false") ||
-        (strncmp("true", propValue, 4) != 0)) {
-        ALOGV("%s: property not set!!! not doing anything", __func__);
-        return;
-    }
     if (asphere_init() != 1) {
         ALOGW("%s: init check failed!!!", __func__);
         return;
@@ -221,14 +239,8 @@
                                       struct str_parms *reply)
 {
     char value[32] = {0};
-    char propValue[PROPERTY_VALUE_MAX] = {0};
     int ret;
 
-    if (!property_get("vendor.audio.pp.asphere.enabled", propValue, "false") ||
-        (strncmp("true", propValue, 4) != 0)) {
-        ALOGV("%s: property not set!!! not doing anything", __func__);
-        return;
-    }
     if (asphere_init() != 1) {
         ALOGW("%s: init check failed!!!", __func__);
         return;
@@ -278,14 +290,8 @@
                                       struct listnode *created_effects)
 {
     struct listnode *node;
-    char propValue[PROPERTY_VALUE_MAX] = {0};
 
     ALOGV("%s: effect %0x", __func__, context->desc->type.timeLow);
-    if (!property_get("vendor.audio.pp.asphere.enabled", propValue, "false") ||
-        (strncmp("true", propValue, 4) != 0)) {
-        ALOGV("%s: property not set!!! not doing anything", __func__);
-        return;
-    }
     if (asphere_init() != 1) {
         ALOGW("%s: init check failed!!!", __func__);
         return;
diff --git a/post_proc/asphere.h b/post_proc/asphere.h
index d0e6830..3babd1d 100644
--- a/post_proc/asphere.h
+++ b/post_proc/asphere.h
@@ -34,17 +34,11 @@
 #include <cutils/list.h>
 #include "bundle.h"
 
-#ifdef AUDIOSPHERE_ENABLED
 void asphere_get_parameters(struct str_parms *query,
                             struct str_parms *reply);
 void asphere_set_parameters(struct str_parms *reply);
 void handle_asphere_on_effect_enabled(bool enable,
                                       effect_context_t *context,
                                       struct listnode *created_effects);
-#else
-#define asphere_get_parameters(query, reply) (0)
-#define asphere_set_parameters(parms)  (0)
-#define handle_asphere_on_effect_enabled(enable, context, created_effects) (0)
-#endif /* AUDIOSPHERE_ENABLED */
 
 #endif /* OFFLOAD_ASPHERE_H_ */
diff --git a/post_proc/ma_listener.c b/post_proc/ma_listener.c
index 02d45d3..04a9047 100644
--- a/post_proc/ma_listener.c
+++ b/post_proc/ma_listener.c
@@ -42,7 +42,8 @@
                                                             i == AUDIO_STREAM_NOTIFICATION ? "Notification":\
                                                             "--INVALID--"); \
 
-#define MA_SET_STATE "audio_hw_send_ma_parameter"
+
+#define MA_SET_STATE "audio_hw_send_qdsp_parameter"
 #define HAL_VENDOR_PATH "/vendor/lib/hw"
 
 enum {
diff --git a/post_proc/virtualizer.c b/post_proc/virtualizer.c
index 0750052..f8a488f 100644
--- a/post_proc/virtualizer.c
+++ b/post_proc/virtualizer.c
@@ -25,12 +25,21 @@
 #include <tinyalsa/asoundlib.h>
 #include <sound/audio_effects.h>
 #include <audio_effects/effect_virtualizer.h>
+#include <audio_feature_manager.h>
+#include <dlfcn.h>
+#include <unistd.h>
 
 #include "effect_api.h"
 #include "virtualizer.h"
 
 #define VIRUALIZER_MAX_LATENCY 30
 
+#define PRIMARY_HAL_PATH XSTR(LIB_AUDIO_HAL)
+#define XSTR(x) STR(x)
+#define STR(x) #x
+
+static bool (*is_feature_enabled)(audio_ext_feature);
+
 #ifdef AUDIO_FEATURE_ENABLED_GCOV
 extern void  __gcov_flush();
 static void enable_gcov()
@@ -104,13 +113,16 @@
  *  true      device is applicable for effect
  */
 bool virtualizer_is_device_supported(audio_devices_t device) {
+    if (is_feature_enabled != NULL &&
+        is_feature_enabled(AFE_PROXY)) {
+        if (device == AUDIO_DEVICE_OUT_PROXY)
+            return false;
+    }
+
     switch (device) {
     case AUDIO_DEVICE_OUT_SPEAKER:
     case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
     case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
-#ifdef AFE_PROXY_ENABLED
-    case AUDIO_DEVICE_OUT_PROXY:
-#endif
     case AUDIO_DEVICE_OUT_AUX_DIGITAL:
     case AUDIO_DEVICE_OUT_USB_ACCESSORY:
     case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
@@ -470,6 +482,20 @@
     ALOGV("%s: ctxt %p", __func__, context);
     virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
 
+    if (access(PRIMARY_HAL_PATH, R_OK) == 0) {
+        void *hal_lib_pointer = dlopen(PRIMARY_HAL_PATH, RTLD_NOW);
+        if (hal_lib_pointer == NULL)
+            ALOGE("%s: DLOPEN failed for %s", __func__, PRIMARY_HAL_PATH);
+        else {
+            is_feature_enabled =
+                     (bool (*)(audio_ext_feature))dlsym(hal_lib_pointer,
+                               "audio_feature_manager_is_feature_enable");
+            if (is_feature_enabled == NULL)
+                ALOGE("%s: dlsym failed", __func__);
+        }
+    } else
+        ALOGE("%s: not able to acces lib %s ", __func__, PRIMARY_HAL_PATH);
+
     context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
     context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;