hal: Send library fd using mixer control

Send the library ion fd to driver to assign the corresponding
memory to DSP for decryption of the decoder library. Also add
non pass-through AC3 and EAC3 as supported formats for secure
playback.

Change-Id: Id318502862969a505f253a75b6e0cf4b8e34c958
diff --git a/hal/audio_extn/hw_loopback.c b/hal/audio_extn/hw_loopback.c
index 180e575..ae27b6a 100644
--- a/hal/audio_extn/hw_loopback.c
+++ b/hal/audio_extn/hw_loopback.c
@@ -382,7 +382,8 @@
         goto exit;
     }
     if (audio_extn_ip_hdlr_intf_supported(source_patch_config->format, false)) {
-        ret = audio_extn_ip_hdlr_intf_init(&inout->ip_hdlr_handle, NULL, NULL);
+        ret = audio_extn_ip_hdlr_intf_init(&inout->ip_hdlr_handle, NULL, NULL, adev,
+                                           USECASE_AUDIO_TRANSCODE_LOOPBACK);
         if (ret < 0) {
             ALOGE("%s: audio_extn_ip_hdlr_intf_init failed %d", __func__, ret);
             inout->ip_hdlr_handle = NULL;
diff --git a/hal/audio_extn/ip_hdlr_intf.c b/hal/audio_extn/ip_hdlr_intf.c
index 0f31f21..6ee06d4 100644
--- a/hal/audio_extn/ip_hdlr_intf.c
+++ b/hal/audio_extn/ip_hdlr_intf.c
@@ -70,6 +70,7 @@
     int (*deinit)(void *handle);
     int (*open)(void *handle, bool is_dsp_decode, void *aud_sess_handle);
     int (*shm_info)(void *handle, int *fd);
+    int (*get_lib_fd)(void *handle, int *lib_fd);
     int (*close)(void *handle);
     int (*event)(void *handle, void *payload);
     int (*reg_cb)(void *handle, void *ack_cb, void *fail_cb);
@@ -416,9 +417,13 @@
     return ret;
 }
 
-int audio_extn_ip_hdlr_intf_init(void **handle, char *lib_path, void **lib_handle)
+int audio_extn_ip_hdlr_intf_init(void **handle, char *lib_path, void **lib_handle,
+                                 struct audio_device *dev, audio_usecase_t usecase)
 {
-    int ret = 0;
+    int ret = 0, pcm_device_id;
+    int lib_fd;
+    struct mixer_ctl *ctl = NULL;
+    char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
 
     if (!ip_hdlr) {
         ip_hdlr = (struct ip_hdlr_intf *)calloc(1, sizeof(struct ip_hdlr_intf));
@@ -444,11 +449,13 @@
                                   void *fail_cb))dlsym(ip_hdlr->lib_hdl, "audio_ip_hdlr_reg_cb");
         ip_hdlr->shm_info =(int (*)(void *handle, int *fd))dlsym(ip_hdlr->lib_hdl,
                                                                  "audio_ip_hdlr_shm_info");
+        ip_hdlr->get_lib_fd =(int (*)(void *handle, int *fd))dlsym(ip_hdlr->lib_hdl,
+                                                                 "audio_ip_hdlr_lib_fd");
         ip_hdlr->event =(int (*)(void *handle, void *payload))dlsym(ip_hdlr->lib_hdl,
                                                                     "audio_ip_hdlr_event");
         if (!ip_hdlr->init || !ip_hdlr->deinit || !ip_hdlr->open ||
             !ip_hdlr->close || !ip_hdlr->reg_cb || !ip_hdlr->shm_info ||
-            !ip_hdlr->event) {
+            !ip_hdlr->event || !ip_hdlr->get_lib_fd) {
             ALOGE("%s: failed to get symbols", __func__);
             ret = -EINVAL;
             goto dlclose;
@@ -462,6 +469,32 @@
         ret = -EINVAL;
         goto dlclose;
     }
+    if (!lib_path) {
+        ip_hdlr->get_lib_fd(*handle, &lib_fd);
+
+        pcm_device_id = platform_get_pcm_device_id(usecase, PCM_PLAYBACK);
+        ret = snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+                       "Playback ION LIB FD %d", pcm_device_id);
+        if (ret < 0) {
+            ALOGE("%s:[%d] snprintf failed",__func__, ip_hdlr->ref_cnt, ret);
+            goto dlclose;
+        }
+        ALOGV("%s: fd = %d  pcm_id = %d", __func__, lib_fd, pcm_device_id);
+
+        ctl = mixer_get_ctl_by_name(dev->mixer, mixer_ctl_name);
+        if (!ctl) {
+            ALOGE("%s:[%d] Could not get ctl for mixer cmd - %s", __func__,
+                  ip_hdlr->ref_cnt, mixer_ctl_name);
+            ret = -EINVAL;
+            goto dlclose;
+        }
+        ret = mixer_ctl_set_array(ctl, &lib_fd, sizeof(lib_fd));
+        if (ret < 0) {
+            ALOGE("%s:[%d] Could not set ctl for mixer cmd - %s, ret %d", __func__, ip_hdlr->ref_cnt,
+                  mixer_ctl_name, ret);
+            goto dlclose;
+        }
+    }
     ip_hdlr->ref_cnt++;
     ALOGD("%s:[%d] init done", __func__, ip_hdlr->ref_cnt);
 
diff --git a/hal/audio_extn/ip_hdlr_intf.h b/hal/audio_extn/ip_hdlr_intf.h
index 1f2c304..b381d7e 100644
--- a/hal/audio_extn/ip_hdlr_intf.h
+++ b/hal/audio_extn/ip_hdlr_intf.h
@@ -35,15 +35,16 @@
 int audio_extn_ip_hdlr_intf_open(void *handle, bool is_dsp_decode, void *aud_sess_handle,
                                  audio_usecase_t usecase);
 int audio_extn_ip_hdlr_intf_close(void *handle, bool is_dsp_decode, void *aud_sess_handle);
-int audio_extn_ip_hdlr_intf_init(void **handle, char *lib_path, void **lib_handle);
+int audio_extn_ip_hdlr_intf_init(void **handle, char *lib_path, void **lib_handle,
+                                 struct audio_device *dev, audio_usecase_t usecase);
 int audio_extn_ip_hdlr_intf_deinit(void *handle);
 bool audio_extn_ip_hdlr_intf_supported(audio_format_t format, bool is_direct_passthru);
 
 #else
 
 #define audio_extn_ip_hdlr_intf_open(handle, is_dsp_decode, aud_sess_handle, usecase)  (0)
-#define audio_extn_ip_hdlr_intf_close(handle, is_dsp_decode, aud_sess_handle) (0)
-#define audio_extn_ip_hdlr_intf_init(handle, lib_path, lib_handle)            (0)
+#define audio_extn_ip_hdlr_intf_close(handle, is_dsp_decode, aud_sess_handle)          (0)
+#define audio_extn_ip_hdlr_intf_init(handle, lib_path, lib_handlei, adev, usecase)     (0)
 #define audio_extn_ip_hdlr_intf_deinit(handle)                                (0)
 #define audio_extn_ip_hdlr_intf_supported(format, is_direct_passthru)                             (0)
 
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 5cfc3f8..f74c23e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -5506,7 +5506,7 @@
         }
     }
     if (audio_extn_ip_hdlr_intf_supported(config->format, audio_extn_passthru_is_direct_passthrough(out))) {
-        ret = audio_extn_ip_hdlr_intf_init(&out->ip_hdlr_handle, NULL, NULL);
+        ret = audio_extn_ip_hdlr_intf_init(&out->ip_hdlr_handle, NULL, NULL, adev, out->usecase);
         if (ret < 0) {
             ALOGE("%s: audio_extn_ip_hdlr_intf_init failed %d",__func__, ret);
             out->ip_hdlr_handle = NULL;