hal: Fix in call music stream muted issue when mic is muted

Fix in-call music stream mute issue when mic is muted within
dialer app. Issue is caused due to mute applied on mixed
voice stream containing both Voice Tx and incall music stream.
Solution is to apply mute on voice device as and when mic is
muted and incall music usecase is active. Mute cannot be
always applied on device as comfort noise can only be applied
after Mute in Voice stream leg

CRs-Fixed:2308665
Change-Id: Ibcb0ef45bbe9a4f906f2016aa70aff2e919eca24
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9ccbcc0..a0f37bc 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2912,6 +2912,9 @@
             adev->offload_effects_stop_output(out->handle, out->pcm_device_id);
     }
 
+    if (out->usecase == USECASE_INCALL_MUSIC_UPLINK)
+        voice_set_device_mute_flag(adev, false);
+
     /* 1. Get and set stream specific mixer controls */
     disable_audio_route(adev, uc_info);
 
@@ -3071,6 +3074,9 @@
          select_devices(adev, out->usecase);
     }
 
+    if (out->usecase == USECASE_INCALL_MUSIC_UPLINK)
+        voice_set_device_mute_flag(adev, true);
+
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
           __func__, adev->snd_card, out->pcm_device_id, out->config.format);
 
diff --git a/hal/voice.c b/hal/voice.c
index f9e3562..fc38ab2 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -228,6 +228,7 @@
 
     uc_info->in_snd_device = SND_DEVICE_NONE;
     uc_info->out_snd_device = SND_DEVICE_NONE;
+    adev->voice.use_device_mute = false;
 
     if (audio_is_bluetooth_sco_device(uc_info->devices) && !adev->bt_sco_on) {
         ALOGE("start_call: couldn't find BT SCO, SCO is not ready");
@@ -338,10 +339,10 @@
        return in_call_rec;
     }
 
-    if(in->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
-       in->source == AUDIO_SOURCE_VOICE_UPLINK ||
-       in->source == AUDIO_SOURCE_VOICE_CALL) {
-       in_call_rec = true;
+    if (in->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
+        in->source == AUDIO_SOURCE_VOICE_UPLINK ||
+        in->source == AUDIO_SOURCE_VOICE_CALL) {
+            in_call_rec = true;
     }
 
     return in_call_rec;
@@ -476,13 +477,21 @@
     int err = 0;
 
     adev->voice.mic_mute = state;
+
     if (audio_extn_hfp_is_active(adev)) {
         err = hfp_set_mic_mute(adev, state);
     } else if (adev->mode == AUDIO_MODE_IN_CALL) {
-        err = platform_set_mic_mute(adev->platform, state);
+       /* Use device mute if incall music delivery usecase is in progress */
+        if (adev->voice.use_device_mute)
+            err = platform_set_device_mute(adev->platform, state, "tx");
+        else
+            err = platform_set_mic_mute(adev->platform, state);
+        ALOGV("%s: voice mute status=%d, use_device_mute flag=%d",
+            __func__, state, adev->voice.use_device_mute);
     } else if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
         err = voice_extn_compress_voip_set_mic_mute(adev, state);
     }
+
     return err;
 }
 
@@ -491,6 +500,27 @@
     return adev->voice.mic_mute;
 }
 
+/*
+ * Following function is called when incall music uplink usecase is
+ * created or destroyed while mic is muted. If incall music uplink
+ * usecase is active, apply voice device mute to mute only voice Tx
+ * path and not the mixed voice Tx + inncall-music path. Revert to
+ * voice stream mute once incall music uplink usecase is inactive
+ */
+void voice_set_device_mute_flag(struct audio_device *adev, bool state)
+{
+    if (adev->voice.mic_mute) {
+        if (state) {
+            platform_set_device_mute(adev->platform, true, "tx");
+            platform_set_mic_mute(adev->platform, false);
+        } else {
+            platform_set_mic_mute(adev->platform, true);
+            platform_set_device_mute(adev->platform, false, "tx");
+        }
+    }
+    adev->voice.use_device_mute = state;
+}
+
 int voice_set_volume(struct audio_device *adev, float volume)
 {
     int vol, err = 0;
diff --git a/hal/voice.h b/hal/voice.h
index 3ae42a8..2ef790a 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -61,6 +61,7 @@
     struct voice_session session[MAX_VOICE_SESSIONS];
     int tty_mode;
     bool mic_mute;
+    bool use_device_mute;
     float volume;
     bool in_call;
 };
@@ -101,4 +102,6 @@
                                       snd_device_t out_snd_device,
                                       bool enable);
 bool voice_is_call_state_active(struct audio_device *adev);
+void voice_set_device_mute_flag (struct audio_device *adev, bool state);
+
 #endif //VOICE_H