Merge "hal: get correspoding sample rate per device when sending cal data"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index efb7d7d..578ed9e 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -689,6 +689,8 @@
 int audio_extn_utils_get_sample_rate_from_string(const char *);
 int audio_extn_utils_get_channels_from_string(const char *);
 void audio_extn_utils_release_snd_device(snd_device_t snd_device);
+int audio_extn_utils_get_app_sample_rate_for_device(struct audio_device *adev,
+                                    struct audio_usecase *usecase, int snd_device);
 
 #ifdef DS2_DOLBY_DAP_ENABLED
 #define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so"
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 3b70c2b..5ee9414 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2014 The Android Open Source Project
@@ -892,6 +892,81 @@
     }
 }
 
+int audio_extn_utils_get_app_sample_rate_for_device(
+                              struct audio_device *adev,
+                              struct audio_usecase *usecase, int snd_device)
+{
+    char value[PROPERTY_VALUE_MAX] = {0};
+    int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+
+    if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out != NULL)) {
+        property_get("vendor.audio.playback.mch.downsample",value,"");
+        if (!strncmp("true", value, sizeof("true"))) {
+            if ((popcount(usecase->stream.out->channel_mask) > 2) &&
+                (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+                !(usecase->stream.out->flags &
+                            (audio_output_flags_t)AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
+               sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        }
+
+        if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
+            usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate;
+        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+        } else if ((snd_device == SND_DEVICE_OUT_HDMI ||
+                    snd_device == SND_DEVICE_OUT_USB_HEADSET ||
+                    snd_device == SND_DEVICE_OUT_DISPLAY_PORT) &&
+                   (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) {
+             /*
+              * To best utlize DSP, check if the stream sample rate is supported/multiple of
+              * configured device sample rate, if not update the COPP rate to be equal to the
+              * device sample rate, else open COPP at stream sample rate
+              */
+              platform_check_and_update_copp_sample_rate(adev->platform, snd_device,
+                                      usecase->stream.out->sample_rate,
+                                      &usecase->stream.out->app_type_cfg.sample_rate);
+        } else if (((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
+                     !audio_is_this_native_usecase(usecase)) &&
+            usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
+            (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
+            /* Reset to default if no native stream is active*/
+            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+                 /*
+                  * For a2dp playback get encoder sampling rate and set copp sampling rate,
+                  * for bit width use the stream param only.
+                  */
+                   audio_extn_a2dp_get_sample_rate(&usecase->stream.out->app_type_cfg.sample_rate);
+                   ALOGI("%s using %d sample rate rate for A2DP CoPP",
+                        __func__, usecase->stream.out->app_type_cfg.sample_rate);
+        }
+        audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.out->app_type_cfg.sample_rate);
+        sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
+
+        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))
+            && audio_extn_passthru_is_passthrough_stream(usecase->stream.out)
+            && !audio_extn_passthru_is_convert_supported(adev, usecase->stream.out)) {
+            sample_rate = sample_rate * 4;
+            if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
+                sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
+        }
+    } else if ((usecase->type == PCM_CAPTURE) && (usecase->stream.in != NULL)) {
+        if (usecase->id == USECASE_AUDIO_RECORD_VOIP)
+            usecase->stream.in->app_type_cfg.sample_rate = usecase->stream.in->sample_rate;
+        if (voice_is_in_call_rec_stream(usecase->stream.in)) {
+            audio_extn_btsco_get_sample_rate(usecase->in_snd_device, &usecase->stream.in->app_type_cfg.sample_rate);
+        } else {
+            audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.in->app_type_cfg.sample_rate);
+        }
+        sample_rate = usecase->stream.in->app_type_cfg.sample_rate;
+    } else if (usecase->type == TRANSCODE_LOOPBACK) {
+        sample_rate = usecase->stream.inout->out_config.sample_rate;
+    }
+    return sample_rate;
+}
+
 static int send_app_type_cfg_for_device(struct audio_device *adev,
                                         struct audio_usecase *usecase,
                                         int split_snd_device)
@@ -903,7 +978,6 @@
     int pcm_device_id = 0, acdb_dev_id, app_type;
     int snd_device = split_snd_device, snd_device_be_idx = -1;
     int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-    char value[PROPERTY_VALUE_MAX] = {0};
     struct streams_io_cfg *s_info = NULL;
     struct listnode *node = NULL;
     int bd_app_type = 0;
@@ -978,51 +1052,9 @@
               snd_device_be_idx);
     }
 
+    sample_rate = audio_extn_utils_get_app_sample_rate_for_device(adev, usecase, snd_device);
+
     if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out != NULL)) {
-
-        property_get("vendor.audio.playback.mch.downsample",value,"");
-        if (!strncmp("true", value, sizeof("true"))) {
-            if ((popcount(usecase->stream.out->channel_mask) > 2) &&
-                   (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
-                   !(usecase->stream.out->flags &
-                            (audio_output_flags_t)AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
-               sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-        }
-
-        if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
-            usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate;
-        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
-            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-        } else if ((snd_device == SND_DEVICE_OUT_HDMI ||
-                    snd_device == SND_DEVICE_OUT_USB_HEADSET ||
-                    snd_device == SND_DEVICE_OUT_DISPLAY_PORT) &&
-                   (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) {
-             /*
-              * To best utlize DSP, check if the stream sample rate is supported/multiple of
-              * configured device sample rate, if not update the COPP rate to be equal to the
-              * device sample rate, else open COPP at stream sample rate
-              */
-              platform_check_and_update_copp_sample_rate(adev->platform, snd_device,
-                                      usecase->stream.out->sample_rate,
-                                      &usecase->stream.out->app_type_cfg.sample_rate);
-        } else if (((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
-                     !audio_is_this_native_usecase(usecase)) &&
-            usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
-            (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
-            /* Reset to default if no native stream is active*/
-            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
-                 /*
-                  * For a2dp playback get encoder sampling rate and set copp sampling rate,
-                  * for bit width use the stream param only.
-                  */
-                   audio_extn_a2dp_get_sample_rate(&usecase->stream.out->app_type_cfg.sample_rate);
-                   ALOGI("%s using %d sample rate rate for A2DP CoPP",
-                        __func__, usecase->stream.out->app_type_cfg.sample_rate);
-        }
-        audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.out->app_type_cfg.sample_rate);
-        sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
-
         /* Interactive streams are supported with only direct app type id.
          * Get Direct profile app type and use it for interactive streams
          */
@@ -1039,16 +1071,6 @@
             app_type = usecase->stream.out->app_type_cfg.app_type;
         app_type_cfg[len++] = app_type;
         app_type_cfg[len++] = acdb_dev_id;
-        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))
-            && audio_extn_passthru_is_passthrough_stream(usecase->stream.out)
-            && !audio_extn_passthru_is_convert_supported(adev, usecase->stream.out)) {
-
-            sample_rate = sample_rate * 4;
-            if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
-                sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
-        }
         app_type_cfg[len++] = sample_rate;
 
         if (snd_device_be_idx > 0)
@@ -1061,14 +1083,6 @@
         app_type = usecase->stream.in->app_type_cfg.app_type;
         app_type_cfg[len++] = app_type;
         app_type_cfg[len++] = acdb_dev_id;
-        if (usecase->id == USECASE_AUDIO_RECORD_VOIP)
-            usecase->stream.in->app_type_cfg.sample_rate = usecase->stream.in->sample_rate;
-        if (voice_is_in_call_rec_stream(usecase->stream.in)) {
-            audio_extn_btsco_get_sample_rate(usecase->in_snd_device, &usecase->stream.in->app_type_cfg.sample_rate);
-        } else {
-            audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.in->app_type_cfg.sample_rate);
-        }
-        sample_rate = usecase->stream.in->app_type_cfg.sample_rate;
         app_type_cfg[len++] = sample_rate;
         if (snd_device_be_idx > 0)
             app_type_cfg[len++] = snd_device_be_idx;
@@ -1077,7 +1091,6 @@
     } else {
         app_type = platform_get_default_app_type_v2(adev->platform, usecase->type);
         if(usecase->type == TRANSCODE_LOOPBACK) {
-            sample_rate = usecase->stream.inout->out_config.sample_rate;
             app_type = usecase->stream.inout->out_app_type_cfg.app_type;
         }
         app_type_cfg[len++] = app_type;
@@ -1433,29 +1446,18 @@
     int type = usecase->type;
 
     if (type == PCM_PLAYBACK && usecase->stream.out != NULL) {
-        struct stream_out *out = usecase->stream.out;
-        int snd_device = usecase->out_snd_device;
-        snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
-                     platform_get_spkr_prot_snd_device(snd_device) : snd_device;
         platform_send_audio_calibration(adev->platform, usecase,
-                                        out->app_type_cfg.app_type,
-                                        usecase->stream.out->app_type_cfg.sample_rate);
+                         usecase->stream.out->app_type_cfg.app_type);
     } else if (type == PCM_CAPTURE && usecase->stream.in != NULL) {
         platform_send_audio_calibration(adev->platform, usecase,
-                         usecase->stream.in->app_type_cfg.app_type,
-                         usecase->stream.in->app_type_cfg.sample_rate);
+                         usecase->stream.in->app_type_cfg.app_type);
     } else if (type == PCM_HFP_CALL || type == PCM_CAPTURE) {
         /* when app type is default. the sample rate is not used to send cal */
         platform_send_audio_calibration(adev->platform, usecase,
-                         platform_get_default_app_type_v2(adev->platform, usecase->type),
-                         48000);
+                         platform_get_default_app_type_v2(adev->platform, usecase->type));
     } else if (type == TRANSCODE_LOOPBACK && usecase->stream.inout != NULL) {
-        int snd_device = usecase->out_snd_device;
-        snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
-                     platform_get_spkr_prot_snd_device(snd_device) : snd_device;
         platform_send_audio_calibration(adev->platform, usecase,
-                         platform_get_default_app_type_v2(adev->platform, usecase->type),
-                         usecase->stream.inout->out_config.sample_rate);
+                         platform_get_default_app_type_v2(adev->platform, usecase->type));
     } else {
         /* No need to send audio calibration for voice and voip call usecases */
         if ((type != VOICE_CALL) && (type != VOIP_CALL))
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 27990a6..5ef38e7 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -3538,7 +3538,7 @@
 }
 
 int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
-                                    int app_type, int sample_rate)
+                                    int app_type)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
@@ -3547,6 +3547,7 @@
     int i, num_devices = 1;
     bool is_incall_rec_usecase = false;
     snd_device_t incall_rec_device;
+    int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
 
     if (voice_is_in_call(my_data->adev))
         is_incall_rec_usecase = voice_is_in_call_rec_stream(usecase->stream.in);
@@ -3576,11 +3577,16 @@
     }
 
     for (i = 0; i < num_devices; i++) {
-        if (!is_incall_rec_usecase)
+        if (!is_incall_rec_usecase) {
             acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(new_snd_device[i])];
-        else
+            sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase,
+                                                          new_snd_device[i]);
+        } else {
             // Use in_call_rec snd_device to extract the ACDB device ID instead of split snd devices
             acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)];
+            sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase,
+                                                          snd_device);
+        }
 
         // Do not use Rx path default app type for TX path
         if ((usecase->type == PCM_CAPTURE) && (app_type == DEFAULT_APP_TYPE_RX_PATH)) {
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index f7a7ebf..9e78bde 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -510,7 +510,7 @@
 }
 
 int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
-                                    int app_type __unused, int sample_rate __unused)
+                                    int app_type __unused)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 948703f..18aeb13 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -3497,7 +3497,7 @@
 }
 
 int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
-                                    int app_type, int sample_rate)
+                                    int app_type)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
@@ -3506,6 +3506,7 @@
     int i, num_devices = 1;
     bool is_incall_rec_usecase = false;
     snd_device_t incall_rec_device;
+    int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
 
     if (voice_is_in_call(my_data->adev))
         is_incall_rec_usecase = voice_is_in_call_rec_stream(usecase->stream.in);
@@ -3540,11 +3541,16 @@
     }
 
     for (i = 0; i < num_devices; i++) {
-        if (!is_incall_rec_usecase)
+        if (!is_incall_rec_usecase) {
             acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(new_snd_device[i])];
-        else
+            sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase,
+                                                          new_snd_device[i]);
+        } else {
             // Use in_call_rec snd_device to extract the ACDB device ID instead of split snd devices
             acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)];
+            sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase,
+                                                          snd_device);
+        }
 
         // Do not use Rx path default app type for TX path
         if ((usecase->type == PCM_CAPTURE) && (app_type == DEFAULT_APP_TYPE_RX_PATH)) {
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 17afefc..e54c496 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -150,7 +150,7 @@
 int platform_set_native_support(int na_mode);
 int platform_get_native_support();
 int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
-                                    int app_type, int sample_rate);
+                                    int app_type);
 int platform_get_default_app_type(void *platform);
 int platform_get_default_app_type_v2(void *platform, usecase_type_t  type);
 int platform_switch_voice_call_device_pre(void *platform);