Merge "hal: Reject hardware NT decoder session during SSR"
diff --git a/hal/Android.mk b/hal/Android.mk
index 4e5f846..e0149f9 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -149,7 +149,7 @@
     LOCAL_SRC_FILES += audio_extn/dolby.c
 endif
 
-ifeq ($(strip $(DOLBY_DAP)),true)
+ifeq ($(strip $(DS1_DOLBY_DAP)),true)
     LOCAL_CFLAGS += -DDS1_DOLBY_DAP_ENABLED
 ifneq ($(strip $(DOLBY_DDP)),true)
     LOCAL_SRC_FILES += audio_extn/dolby.c
@@ -205,8 +205,9 @@
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DS2_DOLBY_DAP)),true)
     LOCAL_CFLAGS += -DDS2_DOLBY_DAP_ENABLED
+    LOCAL_CFLAGS += -DDS1_DOLBY_DDP_ENABLED
 ifneq ($(strip $(DOLBY_DDP)),true)
-    ifneq ($(strip $(DOLBY_DAP)),true)
+    ifneq ($(strip $(DS1_DOLBY_DAP)),true)
         LOCAL_SRC_FILES += audio_extn/dolby.c
     endif
 endif
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index ca5fd59..67d30ca 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -179,6 +179,7 @@
         if (adev->offload_effects_set_hpx_state != NULL)
             adev->offload_effects_set_hpx_state(hpx_state);
 
+        audio_extn_dts_eagle_fade(adev, aextnmod.hpx_enabled, NULL);
         /* set HPX state on device pp */
         ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
         if (ctl)
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 98b2672..e7e2418 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -421,6 +421,7 @@
                                   audio_format_t format,
                                   uint32_t sample_rate,
                                   uint32_t bit_width,
+                                  audio_channel_mask_t channel_mask,
                                   struct stream_app_type_cfg *app_type_cfg);
 int audio_extn_utils_send_app_type_cfg(struct audio_usecase *usecase);
 void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 82b596f..dbd54f7 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -134,14 +134,15 @@
 static audio_output_flags_t parse_flag_names(char *name)
 {
     uint32_t flag = 0;
-    char *flag_name = strtok(name, "|");
+    char *last_r;
+    char *flag_name = strtok_r(name, "|", &last_r);
     while (flag_name != NULL) {
         if (strlen(flag_name) != 0) {
             flag |= string_to_enum(s_flag_name_to_enum_table,
                                ARRAY_SIZE(s_flag_name_to_enum_table),
                                flag_name);
         }
-        flag_name = strtok(NULL, "|");
+        flag_name = strtok_r(NULL, "|", &last_r);
     }
 
     ALOGV("parse_flag_names: flag - %d", flag);
@@ -151,7 +152,8 @@
 static void parse_format_names(char *name, struct streams_output_cfg *so_info)
 {
     struct stream_format *sf_info = NULL;
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0)
         return;
@@ -169,7 +171,7 @@
             sf_info->format = format;
             list_add_tail(&so_info->format_list, &sf_info->list);
         }
-        str = strtok(NULL, "|");
+        str = strtok_r(NULL, "|", &last_r);
     }
 }
 
@@ -177,7 +179,8 @@
 {
     struct stream_sample_rate *ss_info = NULL;
     uint32_t sample_rate = 48000;
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && 0 == strcmp(str, DYNAMIC_VALUE_TAG))
         return;
@@ -188,20 +191,22 @@
         ALOGV("%s: sample_rate - %d", __func__, sample_rate);
         if (0 != sample_rate) {
             ss_info = (struct stream_sample_rate *)calloc(1, sizeof(struct stream_sample_rate));
-            if (ss_info == NULL)
-                break; /* return whatever was parsed */
-
+            if (!ss_info) {
+                ALOGE("%s: memory allocation failure", __func__);
+                return;
+            }
             ss_info->sample_rate = sample_rate;
             list_add_tail(&so_info->sample_rate_list, &ss_info->list);
         }
-        str = strtok(NULL, "|");
+        str = strtok_r(NULL, "|", &last_r);
     }
 }
 
 static int parse_bit_width_names(char *name)
 {
     int bit_width = 16;
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG))
         bit_width = (int)strtol(str, (char **)NULL, 10);
@@ -213,7 +218,8 @@
 static int parse_app_type_names(void *platform, char *name)
 {
     int app_type = platform_get_default_app_type(platform);
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG))
         app_type = (int)strtol(str, (char **)NULL, 10);
@@ -452,12 +458,14 @@
                                   audio_format_t format,
                                   uint32_t sample_rate,
                                   uint32_t bit_width,
+                                  audio_channel_mask_t channel_mask,
                                   struct stream_app_type_cfg *app_type_cfg)
 {
     struct listnode *node_i, *node_j, *node_k;
     struct streams_output_cfg *so_info;
     struct stream_format *sf_info;
     struct stream_sample_rate *ss_info;
+    char value[PROPERTY_VALUE_MAX] = {0};
 
     if ((24 == bit_width) &&
         (devices & AUDIO_DEVICE_OUT_SPEAKER)) {
@@ -468,6 +476,16 @@
         ALOGI("%s Allowing 24-bit playback on speaker ONLY at default sampling rate", __func__);
     }
 
+    property_get("audio.playback.mch.downsample",value,"");
+    if (!strncmp("true", value, sizeof("true"))) {
+        if ((popcount(channel_mask) > 2) &&
+                (sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+                !(flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))  {
+                    sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                    ALOGD("%s: MCH session defaulting sample rate to %d",
+                               __func__, sample_rate);
+        }
+    }
     ALOGV("%s: flags: %x, format: %x sample_rate %d",
            __func__, flags, format, sample_rate);
     list_for_each(node_i, streams_output_cfg_list) {
@@ -509,6 +527,7 @@
     struct mixer_ctl *ctl;
     int pcm_device_id, acdb_dev_id, snd_device = usecase->out_snd_device;
     int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+    char value[PROPERTY_VALUE_MAX] = {0};
 
     ALOGV("%s", __func__);
 
@@ -558,6 +577,14 @@
         sample_rate = out->app_type_cfg.sample_rate;
     }
 
+    property_get("audio.playback.mch.downsample",value,"");
+    if (!strncmp("true", value, sizeof("true"))) {
+        if ((popcount(out->channel_mask) > 2) &&
+               (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+               !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
+           sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+    }
+
     app_type_cfg[len++] = out->app_type_cfg.app_type;
     app_type_cfg[len++] = acdb_dev_id;
     if (((out->format == AUDIO_FORMAT_E_AC3) ||
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index ea4d214..435138d 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -420,7 +420,7 @@
     audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
     audio_extn_utils_send_audio_calibration(adev, usecase);
     audio_extn_utils_send_app_type_cfg(usecase);
-    strcpy(mixer_path, use_case_table[usecase->id]);
+    strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
     platform_add_backend_name(mixer_path, snd_device);
     ALOGV("%s: apply mixer and update path: %s", __func__, mixer_path);
     audio_route_apply_and_update_path(adev->audio_route, mixer_path);
@@ -442,7 +442,7 @@
         snd_device = usecase->in_snd_device;
     else
         snd_device = usecase->out_snd_device;
-    strcpy(mixer_path, use_case_table[usecase->id]);
+    strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
     platform_add_backend_name(mixer_path, snd_device);
     ALOGV("%s: reset and update mixer path: %s", __func__, mixer_path);
     audio_route_reset_and_update_path(adev->audio_route, mixer_path);
@@ -954,6 +954,7 @@
                                                 usecase->stream.out->format,
                                                 usecase->stream.out->sample_rate,
                                                 usecase->stream.out->bit_width,
+                                                usecase->stream.out->channel_mask,
                                                 &usecase->stream.out->app_type_cfg);
         ALOGI("%s Selected apptype: %d", __func__, usecase->stream.out->app_type_cfg.app_type);
     }
@@ -1953,9 +1954,9 @@
             for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
                 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
                     if (!first) {
-                        strcat(value, "|");
+                        strlcat(value, "|", sizeof(value));
                     }
-                    strcat(value, out_channels_name_to_enum_table[j].name);
+                    strlcat(value, out_channels_name_to_enum_table[j].name, sizeof(value));
                     first = false;
                     break;
                 }
@@ -1982,7 +1983,7 @@
             for (j = 0; j < ARRAY_SIZE(out_formats_name_to_enum_table); j++) {
                 if (out_formats_name_to_enum_table[j].value == out->supported_formats[i]) {
                     if (!first) {
-                        strcat(value, "|");
+                        strlcat(value, "|", sizeof(value));
                     }
                     strlcat(value, out_formats_name_to_enum_table[j].name, sizeof(value));
                     first = false;
@@ -2978,7 +2979,8 @@
     audio_extn_utils_update_stream_app_type_cfg(adev->platform,
                                                 &adev->streams_output_cfg_list,
                                                 devices, flags, format, out->sample_rate,
-                                                out->bit_width, &out->app_type_cfg);
+                                                out->bit_width, out->channel_mask,
+                                                &out->app_type_cfg);
     if ((out->usecase == USECASE_AUDIO_PLAYBACK_PRIMARY) ||
         (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
         /* Ensure the default output is not selected twice */
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 356d596..900a2d1 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -59,7 +59,7 @@
 #define MIXER_XML_PATH_WCD9330 "/system/etc/mixer_paths_wcd9330.xml"
 #define MIXER_XML_PATH_WCD9335 "/system/etc/mixer_paths_wcd9335.xml"
 #define PLATFORM_INFO_XML_PATH      "/system/etc/audio_platform_info.xml"
-#define PLATFORM_INFO_XML_PATH_I2S  "/system/etc/audio_platform_info_i2s.xml"
+#define PLATFORM_INFO_XML_PATH_EXTCODEC  "/system/etc/audio_platform_info_extcodec.xml"
 
 #define LIB_ACDB_LOADER "libacdbloader.so"
 #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
@@ -246,22 +246,18 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
                      {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
 #ifdef MULTIPLE_OFFLOAD_ENABLED
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
-                     {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
-                     {PLAYBACK_OFFLOAD_DEVICE3, PLAYBACK_OFFLOAD_DEVICE3},
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD4] =
-                     {PLAYBACK_OFFLOAD_DEVICE4, PLAYBACK_OFFLOAD_DEVICE4},
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD5] =
-                     {PLAYBACK_OFFLOAD_DEVICE5, PLAYBACK_OFFLOAD_DEVICE5},
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD6] =
-                     {PLAYBACK_OFFLOAD_DEVICE6, PLAYBACK_OFFLOAD_DEVICE6},
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD7] =
-                     {PLAYBACK_OFFLOAD_DEVICE7, PLAYBACK_OFFLOAD_DEVICE7},
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD8] =
-                     {PLAYBACK_OFFLOAD_DEVICE8, PLAYBACK_OFFLOAD_DEVICE8},
-    [USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
-                     {PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
+    /* Below entries are initialized with invalid values
+     * Valid values should be updated from fnc platform_info_init()
+     * based on pcm ids defined in audio_platform_info.xml.
+     */
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD2] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD3] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD4] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD5] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD6] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD7] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
 #endif
     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
@@ -1425,7 +1421,7 @@
     DIR *dir;
     struct dirent *dirent;
     char file_name[10] = "wsa";
-    strcat(CodecPeek, snd_card_name);
+    strlcat(CodecPeek, snd_card_name, sizeof(CodecPeek));
 
     dir = opendir(CodecPeek);
     if (dir != NULL) {
@@ -1450,8 +1446,11 @@
 
     set_platform_defaults();
 
-    /* Initialize ACDB ID's */
-    platform_info_init(PLATFORM_INFO_XML_PATH);
+    /* Initialize ACDB and PCM ID's */
+    if (is_external_codec)
+        platform_info_init(PLATFORM_INFO_XML_PATH_EXTCODEC);
+    else
+        platform_info_init(PLATFORM_INFO_XML_PATH);
 
     /* init usb */
     audio_extn_usb_init(adev);
@@ -3473,6 +3472,7 @@
     struct stream_out *out = NULL;
     unsigned int bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
     unsigned int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+    char value[PROPERTY_VALUE_MAX] = {0};
 
     // For voice calls use default configuration
     // force routing is not required here, caller will do it anyway
@@ -3512,6 +3512,22 @@
     if (16 == bit_width) {
         sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
     }
+
+    //check if mulitchannel clip needs to be down sampled to 48k
+    property_get("audio.playback.mch.downsample",value,"");
+    if (!strncmp("true", value, sizeof("true"))) {
+        out = usecase->stream.out;
+        if ((popcount(out->channel_mask) > 2) &&
+                      (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+                      !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
+           sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+          /* update out sample rate to reflect current backend sample rate  */
+           out->sample_rate = sample_rate;
+           ALOGD("%s: MCH session defaulting sample rate to %d",
+                        __func__, sample_rate);
+         }
+    }
+
     // 24 bit playback on speakers is allowed through 48 khz backend only
     // bit width re-configured based on platform info
     if ((24 == bit_width) &&
@@ -3798,7 +3814,7 @@
     strlcpy(mixer_ctl_name, "Playback Channel Map", sizeof(mixer_ctl_name));
     if (snd_id >= 0) {
         snprintf(device_num, sizeof(device_num), "%d", snd_id);
-        strncat(mixer_ctl_name, device_num, 13);
+        strlcat(mixer_ctl_name, device_num, sizeof(device_num));
     }
 
     ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 6d5b4a0..78c9ff8 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -220,17 +220,6 @@
 #define SPKR_PROT_CALIB_TX_PCM_DEVICE 26
 #define PLAYBACK_OFFLOAD_DEVICE 9
 
-#ifdef MULTIPLE_OFFLOAD_ENABLED
-#define PLAYBACK_OFFLOAD_DEVICE2 17
-#define PLAYBACK_OFFLOAD_DEVICE3 18
-#define PLAYBACK_OFFLOAD_DEVICE4 37
-#define PLAYBACK_OFFLOAD_DEVICE5 38
-#define PLAYBACK_OFFLOAD_DEVICE6 39
-#define PLAYBACK_OFFLOAD_DEVICE7 40
-#define PLAYBACK_OFFLOAD_DEVICE8 41
-#define PLAYBACK_OFFLOAD_DEVICE9 42
-#endif
-
 #define COMPRESS_VOIP_CALL_PCM_DEVICE 3
 
 /* Define macro for Internal FM volume mixer */
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index cc2d962..dbfc8ff 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -2647,6 +2647,11 @@
         bool status = false;
         str_parms_del(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE);
         event_name = strtok_r(value, ",", &status_str);
+        if (!event_name) {
+            ret = -EINVAL;
+            ALOGE("%s: event_name is NULL", __func__);
+            goto done;
+        }
         ALOGV("%s: recieved update of external audio device %s %s",
                          __func__,
                          event_name, status_str);
@@ -3132,6 +3137,7 @@
     struct stream_out *out = NULL;
     unsigned int bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
     unsigned int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+    char value[PROPERTY_VALUE_MAX] = {0};
 
     // For voice calls use default configuration
     // force routing is not required here, caller will do it anyway
@@ -3171,6 +3177,21 @@
     if (16 == bit_width) {
         sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
     }
+
+    //check if mulitchannel clip needs to be down sampled  to 48k
+    property_get("audio.playback.mch.downsample",value,"");
+    if (!strncmp("true", value, sizeof("true"))) {
+        out = usecase->stream.out;
+        if ((popcount(out->channel_mask) > 2) &&
+                      (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+                      !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
+            /* update out sample rate to reflect current backend sample rate  */
+            sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            ALOGD("%s: MCH session defaulting sample rate to %d",
+                 __func__, sample_rate);
+        }
+    }
+
     // 24 bit playback on speakers is allowed through 48 khz backend only
     // bit width re-configured based on platform info
     if ((24 == bit_width) &&
@@ -3440,7 +3461,7 @@
 int platform_set_channel_map(void *platform, int ch_count, char *ch_map, int snd_id)
 {
     struct mixer_ctl *ctl;
-    char mixer_ctl_name[44]; // max length of name is 44 as defined
+    char mixer_ctl_name[44] = {0}; // max length of name is 44 as defined
     int ret;
     unsigned int i;
     int set_values[8] = {0};
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index e15db17..2fb79ed 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -110,11 +110,11 @@
     *mixer = mixer_open(card);
     if (!(*mixer)) {
         ALOGE("Failed to open mixer");
-        ctl = NULL;
+        *ctl = NULL;
         return -EINVAL;
     } else {
         *ctl = mixer_get_ctl_by_name(*mixer, mixer_string);
-        if (!(*ctl)) {
+        if (!*ctl) {
             ALOGE("mixer_get_ctl_by_name failed");
             mixer_close(*mixer);
             *mixer = NULL;