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/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;