Merge "Audio V4: Split system and vendor Audio.h"
diff --git a/hal/Android.mk b/hal/Android.mk
index a8b63dd..feb70c7 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -39,17 +39,20 @@
   LOCAL_CFLAGS := -DPLATFORM_MSM8996
   LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
   LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
+  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
   MULTIPLE_HW_VARIANTS_ENABLED := true
 endif
 ifneq ($(filter msm8998,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8998
   LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
   MULTIPLE_HW_VARIANTS_ENABLED := true
 endif
 ifneq ($(filter sdm845,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_SDM845
   LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
   LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
+  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
   MULTIPLE_HW_VARIANTS_ENABLED := true
 endif
 endif
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 77081c7..7037b56 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -287,6 +287,8 @@
 
     [USECASE_AUDIO_PLAYBACK_VOIP] = "audio-playback-voip",
     [USECASE_AUDIO_RECORD_VOIP] = "audio-record-voip",
+
+    [USECASE_INCALL_MUSIC_UPLINK] = "incall-music-uplink",
 };
 
 
@@ -2706,7 +2708,7 @@
             if (out->muted)
                 memset((void *)buffer, 0, bytes);
             // FIXME: this can be removed once audio flinger mixer supports mono output
-            if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
+            if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP || out->usecase == USECASE_INCALL_MUSIC_UPLINK) {
                 size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask);
                 int16_t *src = (int16_t *)buffer;
                 int16_t *dst = (int16_t *)buffer;
@@ -3867,6 +3869,50 @@
         ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
                 __func__, config->offload_info.version,
                 config->offload_info.bit_rate);
+    } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
+        switch (config->sample_rate) {
+            case 0:
+                out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+                break;
+            case 8000:
+            case 16000:
+            case 48000:
+                out->sample_rate = config->sample_rate;
+                break;
+            default:
+                ALOGE("%s: Unsupported sampling rate %d for Incall Music", __func__,
+                      config->sample_rate);
+                config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+                ret = -EINVAL;
+                goto error_open;
+        }
+        //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+        switch (config->channel_mask) {
+            case AUDIO_CHANNEL_NONE:
+            case AUDIO_CHANNEL_OUT_STEREO:
+                out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+                break;
+            default:
+                ALOGE("%s: Unsupported channel mask %#x for Incall Music", __func__,
+                      config->channel_mask);
+                config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+                ret = -EINVAL;
+                goto error_open;
+        }
+        switch (config->format) {
+            case AUDIO_FORMAT_DEFAULT:
+            case AUDIO_FORMAT_PCM_16_BIT:
+                out->format = AUDIO_FORMAT_PCM_16_BIT;
+                break;
+            default:
+                ALOGE("%s: Unsupported format %#x for Incall Music", __func__,
+                      config->format);
+                config->format = AUDIO_FORMAT_PCM_16_BIT;
+                ret = -EINVAL;
+                goto error_open;
+        }
+
+        voice_extn_check_and_set_incall_music_usecase(adev, out);
     } else  if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
         switch (config->sample_rate) {
             case 0:
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 845ce6c..06cacc2 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -131,6 +131,8 @@
     USECASE_AUDIO_PLAYBACK_VOIP,
     USECASE_AUDIO_RECORD_VOIP,
 
+    USECASE_INCALL_MUSIC_UPLINK,
+
     AUDIO_USECASE_MAX
 };
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index c61b8ad..4efd1d2 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -205,6 +205,9 @@
                                      AUDIO_PLAYBACK_VOIP_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_VOIP] = {AUDIO_RECORD_VOIP_PCM_DEVICE,
                                    AUDIO_RECORD_VOIP_PCM_DEVICE},
+
+    [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
+                                     INCALL_MUSIC_UPLINK_PCM_DEVICE},
 };
 
 /* Array to store sound devices */
@@ -587,6 +590,7 @@
     {TO_NAME_INDEX(USECASE_AUDIO_DSM_FEEDBACK)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_VOIP)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_VOIP)},
+    {TO_NAME_INDEX(USECASE_INCALL_MUSIC_UPLINK)},
 };
 
 static const struct name_to_index usecase_type_index[USECASE_TYPE_MAX] = {
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 7c5133b..aebd667 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -314,6 +314,8 @@
 #define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
 #define AFE_PROXY_RECORD_PCM_DEVICE 8
 
+#define INCALL_MUSIC_UPLINK_PCM_DEVICE 27
+
 #define HFP_PCM_RX 5
 #ifdef PLATFORM_MSM8x26
 #ifdef EXTERNAL_BT_SUPPORTED
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 01a1c3f..92b85b6 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -583,22 +583,14 @@
 int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
                                                   struct stream_out *out)
 {
-    uint32_t session_id = 0;
-
-    session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD);
-    if (session_id == VOICE_VSID) {
-        out->usecase = USECASE_INCALL_MUSIC_UPLINK;
-    } else if (session_id == VOICE2_VSID) {
-        out->usecase = USECASE_INCALL_MUSIC_UPLINK2;
-    } else {
-        ALOGE("%s: Invalid session id %x", __func__, session_id);
-        return -EINVAL;
-    }
-
+    out->usecase = USECASE_INCALL_MUSIC_UPLINK;
     out->config = pcm_config_incall_music;
-    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
-    out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
+    //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
+    out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+    out->config.rate = out->sample_rate;
 
+    ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase);
     return 0;
 }
 #endif