Merge 872acb95ba1f98e59b7f7dc5888edbe6a6418475 on remote branch

Change-Id: I3cbed11aa2928c375810290fc5f5be096cf434fb
diff --git a/configs/msm8937/mixer_paths_sdm439_pm8953.xml b/configs/msm8937/mixer_paths_sdm439_pm8953.xml
index 328701c..8fbce19 100644
--- a/configs/msm8937/mixer_paths_sdm439_pm8953.xml
+++ b/configs/msm8937/mixer_paths_sdm439_pm8953.xml
@@ -1317,6 +1317,11 @@
         <path name="headphones" />
     </path>
 
+    <path name="wsa-speaker-and-headphones">
+        <path name="wsa-speaker" />
+        <path name="headphones" />
+    </path>
+
     <path name="usb-headphones">
     </path>
 
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c847291..14d2325 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1025,10 +1025,12 @@
 #ifndef FM_POWER_OPT
 #define audio_extn_fm_set_parameters(adev, parms) (0)
 #define audio_extn_fm_get_parameters(query, reply) (0)
+#define audio_extn_fm_route_on_selected_device(adev, device) (0)
 #else
 void audio_extn_fm_set_parameters(struct audio_device *adev,
                                    struct str_parms *parms);
 void audio_extn_fm_get_parameters(struct str_parms *query, struct str_parms *reply);
+void audio_extn_fm_route_on_selected_device(struct audio_device *adev, audio_devices_t device);
 #endif
 
 #ifndef APTX_DECODER_ENABLED
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index 0a048cd..ade6a7e 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -389,4 +389,25 @@
 exit:
     ALOGV("%s: exit", __func__);
 }
+
+void audio_extn_fm_route_on_selected_device(struct audio_device *adev, audio_devices_t device)
+{
+    struct listnode *node;
+    struct audio_usecase *usecase;
+
+    if (fmmod.is_fm_running) {
+        list_for_each(node, &adev->usecase_list) {
+            usecase = node_to_item(node, struct audio_usecase, list);
+            if (usecase->id == USECASE_AUDIO_PLAYBACK_FM) {
+                if (fmmod.fm_device != device) {
+                    ALOGV("%s selected routing device %x current device %x"
+                          "are different, reroute on selected device", __func__,
+                          fmmod.fm_device, device);
+                    select_devices(adev, usecase->id);
+                }
+            }
+        }
+    }
+}
+
 #endif /* FM_POWER_OPT end */
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 3db4af1..dca98ad 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3698,6 +3698,8 @@
         if (do_stop) {
             stop_output_stream(out);
         }
+        // if fm is active route on selected device in UI
+        audio_extn_fm_route_on_selected_device(adev, out->devices);
         pthread_mutex_unlock(&adev->lock);
     }
     pthread_mutex_unlock(&out->lock);
@@ -7242,7 +7244,8 @@
 
 #ifndef COMPRESS_VOIP_ENABLED
     if (valid_rate && valid_ch &&
-        in->dev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+        (in->dev->mode == AUDIO_MODE_IN_COMMUNICATION ||
+         in->source == AUDIO_SOURCE_VOICE_COMMUNICATION)) {
         in->usecase = USECASE_AUDIO_RECORD_VOIP;
         in->config = default_pcm_config_voip_copp;
         in->config.period_size = VOIP_IO_BUF_SIZE(in->sample_rate,
@@ -7258,8 +7261,9 @@
 #else
     //XXX needed for voice_extn_compress_voip_open_input_stream
     in->config.rate = config->sample_rate;
-    if ((in->dev->mode == AUDIO_MODE_IN_COMMUNICATION ||
-         voice_extn_compress_voip_is_active(in->dev)) &&
+    if((in->dev->mode == AUDIO_MODE_IN_COMMUNICATION ||
+        in->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+        voice_extn_compress_voip_is_active(in->dev)) &&
         (voice_extn_compress_voip_is_format_supported(in->format)) &&
         valid_rate && valid_ch) {
         voice_extn_compress_voip_open_input_stream(in);
@@ -7360,13 +7364,6 @@
     in->bit_width = 16;
     in->af_period_multiplier = 1;
 
-    /* Update config params with the requested sample rate and channels */
-    if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) &&
-          (adev->mode != AUDIO_MODE_IN_CALL)) {
-        ret = -EINVAL;
-        goto err_open;
-    }
-
     if (is_usb_dev && may_use_hifi_record) {
         /* HiFi record selects an appropriate format, channel, rate combo
            depending on sink capabilities*/