hal: enable support for GKI

With introduction of GKI from kernel 5.4, audio hal
needs to support both GKI and non-GKI kernel builds.
Add an audio feature flag which enables support for GKI.

CRs-Fixed: 2605183
Change-Id: I2d7c68d0006940f6f6939649dae0816456f6f902
diff --git a/configs/lahaina/lahaina.mk b/configs/lahaina/lahaina.mk
index e065edd..f9ed3b9 100644
--- a/configs/lahaina/lahaina.mk
+++ b/configs/lahaina/lahaina.mk
@@ -505,3 +505,5 @@
 PRODUCT_PACKAGES_DEBUG += \
     libadpcmdec
 endif
+
+AUDIO_FEATURE_ENABLED_GKI := true
diff --git a/hal/Android.mk b/hal/Android.mk
index 43f5c9c..7929d92 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -326,6 +326,11 @@
     LOCAL_CFLAGS += -DINSTANCE_ID_ENABLED
 endif
 
+# Hardware specific feature
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_GKI)), true)
+    LOCAL_CFLAGS += -DAUDIO_GKI_ENABLED
+endif
+
 # Legacy feature
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_KEEP_ALIVE_ARM_FFV)), true)
     LOCAL_CFLAGS += -DRUN_KEEP_ALIVE_IN_ARM_FFV
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 2d31509..45da9b5 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -3036,6 +3036,114 @@
     audio_extn_aptx_dec_set_license(adev);
 }
 
+#ifdef AUDIO_GKI_ENABLED
+int get_wma_dec_info(struct stream_out *out, struct str_parms *parms) {
+    int ret = 0;
+    char value[32];
+
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma_dec.avg_bit_rate = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma_dec.super_block_align = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma_dec.bits_per_sample = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma_dec.channelmask = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma_dec.encodeopt = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma_dec.encodeopt1 = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma_dec.encodeopt2 = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ALOGV("WMA params: fmt %x, bit rate %x, balgn %x, sr %d, chmsk %x"
+            " encop %x, op1 %x, op2 %x",
+            out->compr_config.codec->format,
+            out->compr_config.codec->options.wma_dec.avg_bit_rate,
+            out->compr_config.codec->options.wma_dec.super_block_align,
+            out->compr_config.codec->options.wma_dec.bits_per_sample,
+            out->compr_config.codec->options.wma_dec.channelmask,
+            out->compr_config.codec->options.wma_dec.encodeopt,
+            out->compr_config.codec->options.wma_dec.encodeopt1,
+            out->compr_config.codec->options.wma_dec.encodeopt2);
+
+    return ret;
+}
+#else
+int get_wma_info(struct stream_out *out, struct str_parms *parms) {
+    int ret = 0;
+    char value[32];
+
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma.avg_bit_rate = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma.super_block_align = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma.bits_per_sample = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma.channelmask = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma.encodeopt = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma.encodeopt1 = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
+    if (ret >= 0) {
+        out->compr_config.codec->options.wma.encodeopt2 = atoi(value);
+        out->is_compr_metadata_avail = true;
+    }
+    ALOGV("WMA params: fmt %x, bit rate %x, balgn %x, sr %d, chmsk %x"
+            " encop %x, op1 %x, op2 %x",
+            out->compr_config.codec->format,
+            out->compr_config.codec->options.wma.avg_bit_rate,
+            out->compr_config.codec->options.wma.super_block_align,
+            out->compr_config.codec->options.wma.bits_per_sample,
+            out->compr_config.codec->options.wma.channelmask,
+            out->compr_config.codec->options.wma.encodeopt,
+            out->compr_config.codec->options.wma.encodeopt1,
+            out->compr_config.codec->options.wma.encodeopt2);
+
+    return ret;
+}
+#endif
+
 int audio_extn_parse_compress_metadata(struct stream_out *out,
                                        struct str_parms *parms)
 {
@@ -3228,51 +3336,11 @@
             out->compr_config.codec->format = atoi(value);
             out->is_compr_metadata_avail = true;
         }
-        ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE, value, sizeof(value));
-        if (ret >= 0) {
-            out->compr_config.codec->options.wma.avg_bit_rate = atoi(value);
-            out->is_compr_metadata_avail = true;
-        }
-        ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
-        if (ret >= 0) {
-            out->compr_config.codec->options.wma.super_block_align = atoi(value);
-            out->is_compr_metadata_avail = true;
-        }
-        ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
-        if (ret >= 0) {
-            out->compr_config.codec->options.wma.bits_per_sample = atoi(value);
-            out->is_compr_metadata_avail = true;
-        }
-        ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
-        if (ret >= 0) {
-            out->compr_config.codec->options.wma.channelmask = atoi(value);
-            out->is_compr_metadata_avail = true;
-        }
-        ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
-        if (ret >= 0) {
-            out->compr_config.codec->options.wma.encodeopt = atoi(value);
-            out->is_compr_metadata_avail = true;
-        }
-        ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
-        if (ret >= 0) {
-            out->compr_config.codec->options.wma.encodeopt1 = atoi(value);
-            out->is_compr_metadata_avail = true;
-        }
-        ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
-        if (ret >= 0) {
-            out->compr_config.codec->options.wma.encodeopt2 = atoi(value);
-            out->is_compr_metadata_avail = true;
-        }
-        ALOGV("WMA params: fmt %x, bit rate %x, balgn %x, sr %d, chmsk %x"
-                " encop %x, op1 %x, op2 %x",
-                out->compr_config.codec->format,
-                out->compr_config.codec->options.wma.avg_bit_rate,
-                out->compr_config.codec->options.wma.super_block_align,
-                out->compr_config.codec->options.wma.bits_per_sample,
-                out->compr_config.codec->options.wma.channelmask,
-                out->compr_config.codec->options.wma.encodeopt,
-                out->compr_config.codec->options.wma.encodeopt1,
-                out->compr_config.codec->options.wma.encodeopt2);
+#ifdef AUDIO_GKI_ENABLED
+	ret = get_wma_dec_info(out, parms);
+#else
+	ret = get_wma_info(out, parms);
+#endif
     }
 
     return ret;
diff --git a/hal/audio_extn/compress_in.c b/hal/audio_extn/compress_in.c
index 6b525b0..fb8834d 100644
--- a/hal/audio_extn/compress_in.c
+++ b/hal/audio_extn/compress_in.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2020, 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
@@ -281,6 +281,7 @@
     struct audio_config config = {.format = 0};
     int ret = 0, buffer_size = 0, meta_size = sizeof(struct snd_codec_metadata);
     cin_private_data_t *cin_data = NULL;
+    uint32_t compr_passthr = 0, flags = 0;
 
     if (!COMPRESSED_TIMESTAMP_FLAG &&
         (in->flags & (AUDIO_INPUT_FLAG_TIMESTAMP | AUDIO_INPUT_FLAG_PASSTHROUGH))) {
@@ -326,17 +327,26 @@
     cin_data->compr_config.codec->format = hal_format_to_alsa(in->format);
 
     if (cin_data->compr_config.codec->id == SND_AUDIOCODEC_PCM)
-        cin_data->compr_config.codec->compr_passthr = LEGACY_PCM;
+        compr_passthr = LEGACY_PCM;
     else if (cin_data->compr_config.codec->id == SND_AUDIOCODEC_IEC61937)
-        cin_data->compr_config.codec->compr_passthr = PASSTHROUGH_IEC61937;
+        compr_passthr = PASSTHROUGH_IEC61937;
     else
-        cin_data->compr_config.codec->compr_passthr = PASSTHROUGH_GEN;
+        compr_passthr = PASSTHROUGH_GEN;
 
     if (in->flags & AUDIO_INPUT_FLAG_FAST) {
         ALOGD("%s: Setting latency mode to true", __func__);
-        cin_data->compr_config.codec->flags |= audio_extn_utils_get_perf_mode_flag();
+        flags |= audio_extn_utils_get_perf_mode_flag();
     }
 
+#ifdef AUDIO_QGKI_ENABLED
+    /* out->compr_config.codec->reserved[0] is for compr_passthr */
+    cin_data->compr_config.codec->reserved[0] = compr_passthr;
+    /* out->compr_config.codec->reserved[1] is for flags */
+    cin_data->compr_config.codec->reserved[1] = flags;
+#else
+    cin_data->compr_config.codec->compr_passthr =  compr_passthr;
+    cin_data->compr_config.codec->flags = flags;
+#endif
     if ((in->flags & AUDIO_INPUT_FLAG_TIMESTAMP) ||
         (in->flags & AUDIO_INPUT_FLAG_PASSTHROUGH)) {
         compress_config_set_timstamp_flag(&cin_data->compr_config);
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index e900932..78a5b7f 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2020, 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
@@ -244,14 +244,21 @@
  */
 bool passthru_should_drop_data(struct stream_out * out)
 {
+    uint32_t compr_passthr = 0;
     /*Drop data only
      *stream is routed to HDMI and
      *stream has PCM format or
      *if a compress offload (DSP decode) session
      */
+#ifdef AUDIO_QGKI_ENABLED
+    /* out->compr_config.codec->reserved[0] is for compr_passthr */
+    compr_passthr = out->compr_config.codec->reserved[0];
+#else
+    compr_passthr = out->compr_config.codec->compr_passthr;
+#endif
     if ((out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
         (((out->format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) ||
-        ((out->compr_config.codec != NULL) && (out->compr_config.codec->compr_passthr == LEGACY_PCM)))) {
+        ((out->compr_config.codec != NULL) && (compr_passthr == LEGACY_PCM)))) {
         if (android_atomic_acquire_load(&compress_passthru_active) > 0) {
             ALOGI("drop data as pass thru is active");
             return true;
@@ -461,21 +468,30 @@
         struct audio_device *adev, struct stream_out *out,
         const void *buffer __unused, size_t bytes __unused)
 {
+    uint32_t compr_passthr = 0;
+
     if(out->compr_config.codec != NULL) {
         if (passthru_is_passt_supported(adev, out)) {
             ALOGV("%s:PASSTHROUGH", __func__);
-            out->compr_config.codec->compr_passthr = PASSTHROUGH;
+            compr_passthr = PASSTHROUGH;
         } else if (passthru_is_convert_supported(adev, out)) {
             ALOGV("%s:PASSTHROUGH CONVERT", __func__);
-            out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
+            compr_passthr = PASSTHROUGH_CONVERT;
         } else if (out->format == AUDIO_FORMAT_IEC61937) {
             ALOGV("%s:PASSTHROUGH IEC61937", __func__);
-            out->compr_config.codec->compr_passthr = PASSTHROUGH_IEC61937;
+            compr_passthr = PASSTHROUGH_IEC61937;
         } else {
             ALOGV("%s:NO PASSTHROUGH", __func__);
-            out->compr_config.codec->compr_passthr = LEGACY_PCM;
+            compr_passthr = LEGACY_PCM;
        }
     }
+
+#ifdef AUDIO_QGKI_ENABLED
+    /* out->compr_config.codec->reserved[0] is for compr_passthr */
+    out->compr_config.codec->reserved[0] = compr_passthr;
+#else
+    out->compr_config.codec->compr_passthr = compr_passthr;
+#endif
 }
 
 bool passthru_is_passthrough_stream(struct stream_out *out)
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index f70883d..337603a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3573,7 +3573,12 @@
         (audio_extn_passthru_is_passthrough_stream(out))) {
         ALOGV("Disable passthrough , reset mixer to pcm");
         /* NO_PASSTHROUGH */
+#ifdef AUDIO_GKI_ENABLED
+        /* out->compr_config.codec->reserved[0] is for compr_passthr */
+        out->compr_config.codec->reserved[0] = 0;
+#else
         out->compr_config.codec->compr_passthr = 0;
+#endif
         audio_extn_passthru_on_stop(out);
         audio_extn_dolby_set_dap_bypass(adev, DAP_STATE_ON);
     }
@@ -5541,6 +5546,7 @@
     const size_t frame_size = audio_stream_out_frame_size(stream);
     const size_t frames = (frame_size != 0) ? bytes / frame_size : bytes;
     struct audio_usecase *usecase = NULL;
+    uint32_t compr_passthr = 0;
 
     ATRACE_BEGIN("out_write");
     lock_output_stream(out);
@@ -5608,8 +5614,15 @@
                 }
             }
 
+#ifdef AUDIO_GKI_ENABLED
+            /* out->compr_config.codec->reserved[0] is for compr_passthr */
+            compr_passthr = out->compr_config.codec->reserved[0];
+#else
+            compr_passthr = out->compr_config.codec->compr_passthr;
+#endif
+
             if ((channels < (int)audio_channel_count_from_out_mask(out->channel_mask)) &&
-                (out->compr_config.codec->compr_passthr == PASSTHROUGH) &&
+                (compr_passthr == PASSTHROUGH) &&
                 (out->is_iec61937_info_available == true)) {
                     ALOGE("%s: ERROR: Unsupported channel config in passthrough mode", __func__);
                     ret = -EINVAL;
@@ -7687,7 +7700,12 @@
 
         if (out->flags & AUDIO_OUTPUT_FLAG_FAST) {
             ALOGD("%s: Setting latency mode to true", __func__);
+#ifdef AUDIO_GKI_ENABLED
+            /* out->compr_config.codec->reserved[1] is for flags */
+            out->compr_config.codec->reserved[1] |= audio_extn_utils_get_perf_mode_flag();
+#else
             out->compr_config.codec->flags |= audio_extn_utils_get_perf_mode_flag();
+#endif
         }
 
         if (out->usecase == USECASE_INVALID) {
@@ -7739,8 +7757,14 @@
             out->bit_width = AUDIO_OUTPUT_BIT_WIDTH;
 
         if (out->flags & AUDIO_OUTPUT_FLAG_TIMESTAMP)
+#ifdef AUDIO_GKI_ENABLED
+            /* out->compr_config.codec->reserved[1] is for flags */
+            out->compr_config.codec->reserved[1] |= COMPRESSED_TIMESTAMP_FLAG;
+        ALOGVV("%s : out->compr_config.codec->flags -> (%#x) ", __func__, out->compr_config.codec->reserved[1]);
+#else
             out->compr_config.codec->flags |= COMPRESSED_TIMESTAMP_FLAG;
         ALOGVV("%s : out->compr_config.codec->flags -> (%#x) ", __func__, out->compr_config.codec->flags);
+#endif
 
         /*TODO: Do we need to change it for passthrough */
         out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_RAW;
@@ -7879,7 +7903,12 @@
         }
         if (config->format == AUDIO_FORMAT_DSD) {
             out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
+#ifdef AUDIO_GKI_ENABLED
+            /* out->compr_config.codec->reserved[0] is for compr_passthr */
+            out->compr_config.codec->reserved[0] = PASSTHROUGH_DSD;
+#else
             out->compr_config.codec->compr_passthr = PASSTHROUGH_DSD;
+#endif
         }
 
         create_offload_callback_thread(out);
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 4a70358..02a819f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -9042,6 +9042,7 @@
     bool passthrough_enabled = false;
     int controller = -1;
     int stream = -1;
+    uint32_t compr_passthr = 0;
 
     if (!usecase) {
         ALOGE("%s: becf: HDMI: usecase is NULL", __func__);
@@ -9067,8 +9068,15 @@
           ", usecase = %d", __func__, bit_width,
           sample_rate, channels, usecase->id);
 
+#ifdef AUDIO_GKI_ENABLED
+    /* out->compr_config.codec->reserved[0] is for compr_passthr */
+    compr_passthr = usecase->stream.out->compr_config.codec->reserved[0];
+#else
+    compr_passthr = usecase->stream.out->compr_config.codec->compr_passthr;
+#endif
+
     if (audio_extn_passthru_is_enabled() && audio_extn_passthru_is_active()
-        && (usecase->stream.out->compr_config.codec->compr_passthr != 0)) {
+        && (compr_passthr != 0)) {
         passthrough_enabled = true;
         ALOGI("passthrough is enabled for this stream");
     }
@@ -9109,7 +9117,7 @@
         if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
             (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
             (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
-            && (usecase->stream.out->compr_config.codec->compr_passthr == PASSTHROUGH)) {
+            && (compr_passthr == PASSTHROUGH)) {
             sample_rate = sample_rate * 4;
             if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
                 sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;