Merge "post_proc: fix compiler warnings" am: f2fdd398aa
am: 560f951ed1

Change-Id: Ib47299d25441d77592755c5bb14a403170030f05
diff --git a/hal/Android.mk b/hal/Android.mk
index 0d2b6b9..923879c 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -161,6 +161,8 @@
     LOCAL_SRC_FILES += audio_extn/sndmonitor.c
 endif
 
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+
 LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
 
 LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index e5d7db4..4edbf9b 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -118,6 +118,8 @@
                                                        "perf_lock_acq");
             if (perf_lock_acq == NULL) {
                 ALOGE("%s: Perf lock Acquire NULL", __func__);
+                dlclose(qcopt_handle);
+                qcopt_handle = NULL;
                 ret = -EINVAL;
                 goto err;
             }
@@ -125,6 +127,8 @@
                                                        "perf_lock_rel");
             if (perf_lock_rel == NULL) {
                 ALOGE("%s: Perf lock Release NULL", __func__);
+                dlclose(qcopt_handle);
+                qcopt_handle = NULL;
                 ret = -EINVAL;
                 goto err;
             }
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 07d5469..07a9711 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <cutils/str_parms.h>
 #include "audio_extn/tfa_98xx.h"
+#include "audio_extn.h"
 
 #define AUDIO_PARAMETER_HFP_ENABLE            "hfp_enable"
 #define AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate"
@@ -247,6 +248,11 @@
     int32_t pcm_dev_rx_id, pcm_dev_tx_id, pcm_dev_asm_rx_id, pcm_dev_asm_tx_id;
 
     ALOGD("%s: enter", __func__);
+
+    if (adev->enable_hfp == true) {
+        ALOGD("%s: HFP is already active!\n", __func__);
+        return 0;
+    }
     adev->enable_hfp = true;
     platform_set_mic_mute(adev->platform, false);
 
diff --git a/hal/audio_extn/hwdep_cal.c b/hal/audio_extn/hwdep_cal.c
index 811db3e..07269d1 100644
--- a/hal/audio_extn/hwdep_cal.c
+++ b/hal/audio_extn/hwdep_cal.c
@@ -24,6 +24,7 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <unistd.h>
 #include <cutils/log.h>
 #include <audio_hw.h>
 #include "audio_extn.h"
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index 3c91dda..9b44742 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -36,6 +36,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/poll.h>
+#include <pthread.h>
 #include <cutils/list.h>
 #include <cutils/hashmap.h>
 #include <cutils/log.h>
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index 112bd1e..3417c72 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -21,6 +21,8 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
 #include <cutils/log.h>
 #include "audio_hw.h"
 #include "audio_extn.h"
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 743ba58..dc1afa1 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -22,6 +22,7 @@
 #include <cutils/log.h>
 #include <cutils/str_parms.h>
 #include <sys/ioctl.h>
+#include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <system/audio.h>
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 1f52590..12957d5 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -22,6 +22,7 @@
 #include <cutils/config_utils.h>
 #include <stdlib.h>
 #include <dlfcn.h>
+#include <unistd.h>
 #include <cutils/str_parms.h>
 #include <cutils/log.h>
 #include <cutils/misc.h>
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 7f91a24..7267931 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -49,7 +49,6 @@
 #include <audio_effects/effect_aec.h>
 #include <audio_effects/effect_ns.h>
 #include <audio_utils/clock.h>
-#include <audio_utils/power.h>
 #include "audio_hw.h"
 #include "audio_extn.h"
 #include "platform_api.h"
@@ -99,6 +98,7 @@
 #define MMAP_PERIOD_COUNT_MAX 512
 #define MMAP_PERIOD_COUNT_DEFAULT (MMAP_PERIOD_COUNT_MAX)
 
+static const int64_t NANOS_PER_SECOND = 1000000000;
 
 /* This constant enables extended precision handling.
  * TODO The flag is off until more testing is done.
@@ -320,14 +320,6 @@
 //cache last MBDRC cal step level
 static int last_known_cal_step = -1 ;
 
-// TODO: Consider moving this to a pthread_once() if we have more
-// static initialization required.
-static bool is_userdebug_or_eng_build() {
-    char value[PROPERTY_VALUE_MAX];
-    (void)property_get("ro.build.type", value, "unknown"); // ignore actual length
-    return strcmp(value, "userdebug") == 0 || strcmp(value, "eng") == 0;
-}
-
 static bool may_use_noirq_mode(struct audio_device *adev, audio_usecase_t uc_id,
                                int flags __unused)
 {
@@ -451,6 +443,12 @@
     return 0;
 }
 
+// always call with adev lock held
+void send_gain_dep_calibration_l() {
+    if (last_known_cal_step >= 0)
+        platform_send_gain_dep_cal(adev->platform, last_known_cal_step);
+}
+
 __attribute__ ((visibility ("default")))
 bool audio_hw_send_gain_dep_calibration(int level) {
     bool ret_val = false;
@@ -460,15 +458,9 @@
 
     if (adev != NULL && adev->platform != NULL) {
         pthread_mutex_lock(&adev->lock);
-        ret_val = platform_send_gain_dep_cal(adev->platform, level);
+        last_known_cal_step = level;
+        send_gain_dep_calibration_l();
         pthread_mutex_unlock(&adev->lock);
-
-        // if cal set fails, cache level info
-        // if cal set succeds, reset known last cal set
-        if (!ret_val)
-            last_known_cal_step = level;
-        else if (last_known_cal_step != -1)
-            last_known_cal_step = -1;
     } else {
         ALOGE("%s: %s is NULL", __func__, adev == NULL ? "adev" : "adev->platform");
     }
@@ -695,9 +687,12 @@
             audio_extn_spkr_prot_is_enabled()) {
             audio_extn_spkr_prot_stop_processing(snd_device);
 
+            // FIXME b/65363602: bullhead is the only Nexus with audio_extn_spkr_prot_is_enabled()
+            // and does not use speaker swap. As this code causes a problem with device enable ref
+            // counting we remove it for now.
             // when speaker device is disabled, reset swap.
             // will be renabled on usecase start
-            platform_set_swap_channels(adev, false);
+            // platform_set_swap_channels(adev, false);
 
         } else if (platform_can_split_snd_device(snd_device,
                                                  &num_devices,
@@ -1172,6 +1167,8 @@
     audio_usecase_t hfp_ucid;
     struct listnode *node;
     int status = 0;
+    struct audio_usecase *voip_usecase = get_usecase_from_list(adev,
+                                             USECASE_AUDIO_PLAYBACK_VOIP);
 
     usecase = get_usecase_from_list(adev, uc_id);
     if (usecase == NULL) {
@@ -1214,13 +1211,18 @@
             usecase->devices = usecase->stream.out->devices;
             in_snd_device = SND_DEVICE_NONE;
             if (out_snd_device == SND_DEVICE_NONE) {
+                struct stream_out *voip_out = adev->primary_output;
+
                 out_snd_device = platform_get_output_snd_device(adev->platform,
                                             usecase->stream.out->devices);
-                if (usecase->stream.out == adev->primary_output &&
+
+                if (voip_usecase)
+                    voip_out = voip_usecase->stream.out;
+
+                if (usecase->stream.out == voip_out &&
                         adev->active_input &&
                         (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
-                            adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
-                        out_snd_device != usecase->out_snd_device) {
+                            adev->mode == AUDIO_MODE_IN_COMMUNICATION)) {
                     select_devices(adev, adev->active_input->usecase);
                 }
             }
@@ -1232,9 +1234,15 @@
                 if (adev->active_input &&
                         (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
                             adev->mode == AUDIO_MODE_IN_COMMUNICATION)) {
+
+                    struct audio_usecase *voip_usecase = get_usecase_from_list(adev,
+                                                             USECASE_AUDIO_PLAYBACK_VOIP);
+
                     platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
                     if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
                         out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
+                    } else if (voip_usecase) {
+                        out_device = voip_usecase->stream.out->devices;
                     } else if (adev->primary_output) {
                         out_device = adev->primary_output->devices;
                     }
@@ -1355,6 +1363,12 @@
             voice_set_sidetone(adev, out_snd_device, true);
     }
 
+    if (usecase == voip_usecase) {
+        struct stream_out *voip_out = voip_usecase->stream.out;
+        audio_extn_utils_send_app_type_gain(adev,
+                                            voip_out->app_type_cfg.app_type,
+                                            &voip_out->app_type_cfg.gain[0]);
+    }
     return status;
 }
 
@@ -1941,9 +1955,6 @@
     register_out_stream(out);
     audio_extn_perf_lock_release();
     audio_extn_tfa_98xx_enable_speaker();
-    audio_extn_utils_send_app_type_gain(out->dev,
-                                        out->app_type_cfg.app_type,
-                                        &out->app_type_cfg.gain[0]);
 
     // consider a scenario where on pause lower layers are tear down.
     // so on resume, swap mixer control need to be sent only when
@@ -2159,9 +2170,7 @@
     // dump error info
     (void)error_log_dump(
             out->error_log, fd, "      " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
-    // dump power info (out->power_log may be null)
-    (void)power_log_dump(
-            out->power_log, fd, "      " /* prefix */, POWER_LOG_LINES, 0 /* limit_ns */);
+
     return 0;
 }
 
@@ -2610,17 +2619,19 @@
         out->standby = false;
         pthread_mutex_lock(&adev->lock);
         ret = start_output_stream(out);
-        pthread_mutex_unlock(&adev->lock);
+
         /* ToDo: If use case is compress offload should return 0 */
         if (ret != 0) {
             out->standby = true;
+            pthread_mutex_unlock(&adev->lock);
             goto exit;
         }
 
-        if (last_known_cal_step != -1) {
-            ALOGD("%s: retry previous failed cal level set", __func__);
-            audio_hw_send_gain_dep_calibration(last_known_cal_step);
-        }
+        // after standby always force set last known cal step
+        // dont change level anywhere except at the audio_hw_send_gain_dep_calibration
+        ALOGD("%s: retry previous failed cal level set", __func__);
+        send_gain_dep_calibration_l();
+        pthread_mutex_unlock(&adev->lock);
     }
 
     if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -2667,20 +2678,35 @@
     } else {
         error_code = ERROR_CODE_WRITE;
         if (out->pcm) {
+            size_t bytes_to_write = bytes;
+
             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) {
+                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;
 
-            ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes);
+                LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 ||
+                                    out->format != AUDIO_FORMAT_PCM_16_BIT,
+                                    "out_write called for VOIP use case with wrong properties");
 
-            long ns = pcm_bytes_to_frames(out->pcm, bytes)*1000000000LL/
-                                                out->config.rate;
+                for (size_t i = 0; i < frames ; i++, dst++, src += 2) {
+                    *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
+                }
+                bytes_to_write /= 2;
+            }
+            ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes_to_write);
+
+            long ns = (frames * NANOS_PER_SECOND) / out->config.rate;
             request_out_focus(out, ns);
 
             bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime;
             if (use_mmap)
-                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
+                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes_to_write);
             else
-                ret = pcm_write(out->pcm, (void *)buffer, bytes);
+                ret = pcm_write(out->pcm, (void *)buffer, bytes_to_write);
 
             release_out_focus(out, ns);
         } else {
@@ -2695,13 +2721,8 @@
     }
     long long sleeptime_us = 0;
 
-    // only get time if needed for logging, as it is a system call on 32 bit devices.
-    // TODO: Consider always enabling for 64 bit vDSO using compile time check on __LP64__.
-    const int64_t now_ns = out->power_log != 0 || (ret != 0 && out->error_log != 0)
-            ? audio_utils_get_real_time_ns() : 0;
-
     if (ret != 0) {
-        error_log_log(out->error_log, error_code, now_ns);
+        error_log_log(out->error_log, error_code, audio_utils_get_real_time_ns());
         if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
             ALOGE_IF(out->pcm != NULL,
                     "%s: error %zd - %s", __func__, ret, pcm_get_error(out->pcm));
@@ -2716,9 +2737,6 @@
         out_on_error(&out->stream.common);
         if (sleeptime_us != 0)
             usleep(sleeptime_us);
-    } else {
-        // only log if the data is properly written (out->power_log may be null)
-        power_log_log(out->power_log, buffer, frames, now_ns);
     }
     return bytes;
 }
@@ -3143,8 +3161,25 @@
     return status;
 }
 
-static int in_dump(const struct audio_stream *stream __unused, int fd __unused)
+static int in_dump(const struct audio_stream *stream, int fd)
 {
+    struct stream_in *in = (struct stream_in *)stream;
+
+    // We try to get the lock for consistency,
+    // but it isn't necessary for these variables.
+    // If we're not in standby, we may be blocked on a read.
+    const bool locked = (pthread_mutex_trylock(&in->lock) == 0);
+    dprintf(fd, "      Standby: %s\n", in->standby ? "yes" : "no");
+    dprintf(fd, "      Frames read: %lld\n", (long long)in->frames_read);
+    dprintf(fd, "      Frames muted: %lld\n", (long long)in->frames_muted);
+
+    if (locked) {
+        pthread_mutex_unlock(&in->lock);
+    }
+
+    // dump error info
+    (void)error_log_dump(
+            in->error_log, fd, "      " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
     return 0;
 }
 
@@ -3289,6 +3324,7 @@
     struct audio_device *adev = in->dev;
     int i, ret = -1;
     int *int_buf_stream = NULL;
+    int error_code = ERROR_CODE_STANDBY; // initial errors are considered coming out of standby.
 
     lock_input_stream(in);
     const size_t frame_size = audio_stream_in_frame_size(stream);
@@ -3317,6 +3353,9 @@
         in->standby = 0;
     }
 
+    // errors that occur here are read errors.
+    error_code = ERROR_CODE_READ;
+
     //what's the duration requested by the client?
     long ns = pcm_bytes_to_frames(in->pcm, bytes)*1000000000LL/
                                                 in->config.rate;
@@ -3355,17 +3394,21 @@
      * to always provide zeroes when muted.
      * No need to acquire adev->lock to read mic_muted here as we don't change its state.
      */
-    if (ret == 0 && adev->mic_muted && in->usecase != USECASE_AUDIO_RECORD_AFE_PROXY)
+    if (ret == 0 && adev->mic_muted && in->usecase != USECASE_AUDIO_RECORD_AFE_PROXY) {
         memset(buffer, 0, bytes);
+        in->frames_muted += frames;
+    }
 
 exit:
     pthread_mutex_unlock(&in->lock);
 
     if (ret != 0) {
+        error_log_log(in->error_log, error_code, audio_utils_get_real_time_ns());
         in_standby(&in->stream.common);
         ALOGV("%s: read failed - sleeping for buffer duration", __func__);
         usleep(frames * 1000000LL / in_get_sample_rate(&in->stream.common));
         memset(buffer, 0, bytes); // clear return data
+        in->frames_muted += frames;
     }
     if (bytes > 0) {
         in->frames_read += frames;
@@ -3431,10 +3474,8 @@
             struct listnode *node;
             list_for_each(node, &adev->usecase_list) {
                 usecase = node_to_item(node, struct audio_usecase, list);
-                if (usecase->type == PCM_PLAYBACK) {
+                if (usecase->type == PCM_PLAYBACK)
                     select_devices(adev, usecase->id);
-                    break;
-                }
             }
         }
         if (!in->standby)
@@ -3783,17 +3824,13 @@
         out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY;
         out->config = pcm_config_afe_proxy_playback;
         adev->voice_tx_output = out;
-    } else if (out->flags == (AUDIO_OUTPUT_FLAG_DIRECT |
-                              AUDIO_OUTPUT_FLAG_VOIP_RX)) {
+    } else if (out->flags == AUDIO_OUTPUT_FLAG_VOIP_RX) {
+        //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
         uint32_t buffer_size, frame_size;
-        out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
-        out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
         out->usecase = USECASE_AUDIO_PLAYBACK_VOIP;
         out->config = pcm_config_voip;
         out->config.format = pcm_format_from_audio_format(config->format);
         out->config.rate = config->sample_rate;
-        out->config.channels =
-                audio_channel_count_from_out_mask(config->channel_mask);
         buffer_size = get_stream_buffer_size(VOIP_PLAYBACK_PERIOD_DURATION_MSEC,
                                              config->sample_rate,
                                              config->format,
@@ -3910,20 +3947,6 @@
             ERROR_LOG_ENTRIES,
             1000000000 /* aggregate consecutive identical errors within one second in ns */);
 
-    // power_log may be null if the format is not supported
-    // or not a userdebug or eng build.
-    if (false /* is_userdebug_or_eng_build() */) {
-        const size_t POWER_LOG_FRAMES_PER_ENTRY =
-                (long long)config->sample_rate * POWER_LOG_SAMPLING_INTERVAL_MS / 1000;
-
-        out->power_log = power_log_create(
-                config->sample_rate,
-                audio_channel_count_from_out_mask(config->channel_mask),
-                config->format,
-                POWER_LOG_ENTRIES,
-                POWER_LOG_FRAMES_PER_ENTRY);
-    }
-
     /*
        By locking output stream before registering, we allow the callback
        to update stream's state only after stream's initial state is set to
@@ -3972,9 +3995,6 @@
     if (adev->voice_tx_output == out)
         adev->voice_tx_output = NULL;
 
-    power_log_destroy(out->power_log);
-    out->power_log = NULL;
-
     error_log_destroy(out->error_log);
     out->error_log = NULL;
 
@@ -4483,6 +4503,10 @@
     in->config.channels = channel_count;
     in->sample_rate  = in->config.rate;
 
+    in->error_log = error_log_create(
+            ERROR_LOG_ENTRIES,
+            NANOS_PER_SECOND /* aggregate consecutive identical errors within one second */);
+
     /* This stream could be for sound trigger lab,
        get sound trigger pcm if present */
     audio_extn_sound_trigger_check_and_get_session(in);
@@ -4509,12 +4533,17 @@
 static void adev_close_input_stream(struct audio_hw_device *dev __unused,
                                     struct audio_stream_in *stream)
 {
+    struct stream_in *in = (struct stream_in *)stream;
     ALOGV("%s", __func__);
 
     // must deregister from sndmonitor first to prevent races
     // between the callback and close_stream
     audio_extn_snd_mon_unregister_listener(stream);
     in_standby(&stream->common);
+
+    error_log_destroy(in->error_log);
+    in->error_log = NULL;
+
     free(stream);
 
     return;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 46384a2..a588eef 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -26,7 +26,6 @@
 
 #include <audio_route/audio_route.h>
 #include <audio_utils/ErrorLog.h>
-#include <audio_utils/PowerLog.h>
 #include "voice.h"
 
 // dlopen() does not go through default library path search if there is a "/" in the library name.
@@ -57,15 +56,11 @@
 
 #define ERROR_LOG_ENTRIES 16
 
-#define POWER_LOG_LINES 40
-#define POWER_LOG_SAMPLING_INTERVAL_MS 50
-#define POWER_LOG_ENTRIES (1 /* minutes */ * 60 /* seconds */ * 1000 /* msec */ \
-                           / POWER_LOG_SAMPLING_INTERVAL_MS)
-
 /* Error types for the error log */
 enum {
     ERROR_CODE_STANDBY = 1,
     ERROR_CODE_WRITE,
+    ERROR_CODE_READ,
 };
 
 typedef enum card_status_t {
@@ -223,7 +218,6 @@
     card_status_t card_status;
 
     error_log_t *error_log;
-    power_log_t *power_log;
 
     struct stream_app_type_cfg app_type_cfg;
 };
@@ -244,6 +238,7 @@
     bool enable_aec;
     bool enable_ns;
     int64_t frames_read; /* total frames read, not cleared when entering standby */
+    int64_t frames_muted; /* total frames muted, not cleared when entering standby */
 
     audio_io_handle_t capture_handle;
     audio_input_flags_t flags;
@@ -263,6 +258,8 @@
     audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
     audio_format_t supported_formats[MAX_SUPPORTED_FORMATS + 1];
     uint32_t supported_sample_rates[MAX_SUPPORTED_SAMPLE_RATES + 1];
+
+    error_log_t *error_log;
 };
 
 typedef enum usecase_type_t {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e27caf0..6560d14 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -19,6 +19,8 @@
 
 #include <stdlib.h>
 #include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
 #include <cutils/log.h>
 #include <cutils/str_parms.h>
 #include <cutils/properties.h>
@@ -746,7 +748,6 @@
     if (!voice_is_in_call(adev)) {
         ALOGV("%s: Not Voice call usecase, apply new cal for level %d",
                __func__, level);
-        app_type = DEFAULT_APP_TYPE_RX_PATH;
 
         // find the current active sound device
         list_for_each(node, &adev->usecase_list) {
@@ -758,18 +759,23 @@
             if (valid_uc_type) {
                 audio_devices_t dev = usecase->stream.out->devices;
                 valid_dev = (dev == AUDIO_DEVICE_OUT_SPEAKER ||
+                             dev == AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
                              dev == AUDIO_DEVICE_OUT_WIRED_HEADSET ||
                              dev == AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
             }
             if (valid_dev) {
-                 ALOGV("%s: out device is %d", __func__,  usecase->out_snd_device);
-                 if (audio_extn_spkr_prot_is_enabled()) {
-                    acdb_dev_id = audio_extn_spkr_prot_get_acdb_id(usecase->out_snd_device);
-                 } else {
-                     acdb_dev_id = acdb_device_table[usecase->out_snd_device];
-                 }
+                ALOGV("%s: out device is %d", __func__,  usecase->out_snd_device);
+                if (platform_supports_app_type_cfg())
+                    app_type = usecase->stream.out->app_type_cfg.app_type;
+                else
+                    app_type = DEFAULT_APP_TYPE_RX_PATH;
 
-                 if (!my_data->acdb_send_gain_dep_cal(acdb_dev_id, app_type,
+                if (audio_extn_spkr_prot_is_enabled())
+                    acdb_dev_id = audio_extn_spkr_prot_get_acdb_id(usecase->out_snd_device);
+                else
+                    acdb_dev_id = acdb_device_table[usecase->out_snd_device];
+
+                if (!my_data->acdb_send_gain_dep_cal(acdb_dev_id, app_type,
                                                      acdb_dev_type, mode, level)) {
                     // set ret_val true if at least one calibration is set successfully
                     ret_val = true;
@@ -1080,6 +1086,11 @@
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_NS] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_AEC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_NS] = strdup("SLIMBUS_0_TX");
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 283936e..41b59c8 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -216,6 +216,9 @@
     tbl_entry.amp = exp(tbl_entry.db * 0.115129f);
     tbl_entry.level = atoi(attr[3]);
 
+    //custome level should be > 0. Level 0 is fixed for default
+    CHECK(tbl_entry.level > 0);
+
     ALOGV("%s: amp [%f]  db [%f] level [%d]", __func__,
            tbl_entry.amp, tbl_entry.db, tbl_entry.level);
     platform_add_gain_level_mapping(&tbl_entry);
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 493f2cc..f1174a0 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -30,6 +30,8 @@
 	external/tinyalsa/include \
 	$(call include-path-for, audio-effects)
 
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
 include $(BUILD_SHARED_LIBRARY)
 endif
 
@@ -60,6 +62,8 @@
         hardware/qcom/audio/hal \
 	$(call include-path-for, audio-effects)
 
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
 include $(BUILD_SHARED_LIBRARY)
 
 endif
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index f83e231..2996d8e 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -17,7 +17,9 @@
 #define LOG_TAG "offload_effect_bundle"
 //#define LOG_NDEBUG 0
 
+#include <pthread.h>
 #include <stdlib.h>
+
 #include <cutils/list.h>
 #include <cutils/log.h>
 #include <system/thread_defs.h>
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index 9c15e8f..37728db 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -17,8 +17,10 @@
 #define LOG_TAG "offload_effect_api"
 //#define LOG_NDEBUG 0
 
+#include <stdio.h>
 #include <errno.h>
 #include <stdbool.h>
+
 #include <cutils/log.h>
 #include <tinyalsa/asoundlib.h>
 #include <sound/audio_effects.h>
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
index cb83808..0fb62cb 100644
--- a/post_proc/volume_listener.c
+++ b/post_proc/volume_listener.c
@@ -19,6 +19,8 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <math.h>
+#include <pthread.h>
+#include <unistd.h>
 
 #include <cutils/list.h>
 #include <cutils/log.h>
@@ -239,7 +241,8 @@
 
 static inline bool valid_dev_in_context(struct vol_listener_context_s *context)
 {
-    if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER)
+    if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER ||
+        context->dev_id == AUDIO_DEVICE_OUT_SPEAKER_SAFE)
         return true;
 
     if (context->stream_type == VC_CALL && headset_cal_enabled &&
@@ -318,20 +321,22 @@
                     // decision made .. send new level now
                     if (!send_gain_dep_cal(gain_dep_cal_level)) {
                         ALOGE("%s: Failed to set gain dep cal level", __func__);
-                    } else {
-                        // Success in setting the gain dep cal level, store new level and Volume
-                        if (dumping_enabled) {
-                            ALOGW("%s: (old/new) Volume (%f/%f) (old/new) level (%d/%d)",
-                                  __func__, current_vol, new_vol, current_gain_dep_cal_level,
-                                  gain_dep_cal_level);
-                        } else {
-                            ALOGV("%s: Change in Cal::(old/new) Volume (%f/%f) (old/new) level (%d/%d)",
-                                  __func__, current_vol, new_vol, current_gain_dep_cal_level,
-                                  gain_dep_cal_level);
-                        }
-                        current_gain_dep_cal_level = gain_dep_cal_level;
-                        current_vol = new_vol;
                     }
+
+                    if (dumping_enabled) {
+                        ALOGW("%s: (old/new) Volume (%f/%f) (old/new) level (%d/%d)",
+                              __func__, current_vol, new_vol, current_gain_dep_cal_level,
+                              gain_dep_cal_level);
+                    } else {
+                        ALOGV("%s: Change in Cal::(old/new) Volume (%f/%f) (old/new) level (%d/%d)",
+                              __func__, current_vol, new_vol, current_gain_dep_cal_level,
+                              gain_dep_cal_level);
+                    }
+
+                    // Gain level change info send to lower layer that has logic to re-apply on
+                    // failure, so change current gain level to reflect new level
+                    current_gain_dep_cal_level = gain_dep_cal_level;
+                    current_vol = new_vol;
                 } else {
                     if (dumping_enabled) {
                         ALOGW("%s: volume changed but gain dep cal level is still the same",
@@ -515,7 +520,8 @@
 
         // check if old or new device is speaker
         if (valid_dev_in_context(context) ||
-            new_device == AUDIO_DEVICE_OUT_SPEAKER) {
+            new_device == AUDIO_DEVICE_OUT_SPEAKER ||
+            new_device == AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
             recompute_gain_dep_cal_Level = true;
         }
 
diff --git a/visualizer/Android.mk b/visualizer/Android.mk
index e318214..7af76ec 100644
--- a/visualizer/Android.mk
+++ b/visualizer/Android.mk
@@ -27,6 +27,16 @@
 	libdl \
 	libtinyalsa
 
+# HACK to set the right record proxy effect card number.
+# It should be retrieved from the primary hal USECASE_AUDIO_RECORD_AFE_PROXY.
+ifneq ($(filter msm8998,$(TARGET_BOARD_PLATFORM)),)
+  LOCAL_CFLAGS := -DCAPTURE_DEVICE=7
+else
+  LOCAL_CFLAGS := -DCAPTURE_DEVICE=8
+endif
+
+LOCAL_HEADER_LIBRARIES := libhardware_headers
+
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libqcomvisualizer
 LOCAL_MODULE_OWNER := qcom
@@ -36,4 +46,5 @@
 	external/tinyalsa/include \
 	$(call include-path-for, audio-effects)
 
+LOCAL_HEADER_LIBRARIES += libsystem_headers
 include $(BUILD_SHARED_LIBRARY)
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 4d1373f..860dfce 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -17,12 +17,14 @@
 #define LOG_TAG "offload_visualizer"
 /*#define LOG_NDEBUG 0*/
 #include <assert.h>
+#include <dlfcn.h>
 #include <math.h>
+#include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
 #include <sys/prctl.h>
-#include <dlfcn.h>
+#include <time.h>
+#include <unistd.h>
 
 #include <cutils/list.h>
 #include <cutils/log.h>
@@ -179,7 +181,6 @@
 
 #define MIXER_CARD 0
 #define SOUND_CARD 0
-#define CAPTURE_DEVICE 8
 
 /* Proxy port supports only MMAP read and those fixed parameters*/
 #define AUDIO_CAPTURE_CHANNEL_COUNT 2
diff --git a/voice_processing/Android.mk b/voice_processing/Android.mk
index e8878ee..7ebeb70 100644
--- a/voice_processing/Android.mk
+++ b/voice_processing/Android.mk
@@ -23,4 +23,5 @@
 
 LOCAL_CFLAGS += -fvisibility=hidden
 
+LOCAL_HEADER_LIBRARIES += libhardware_headers
 include $(BUILD_SHARED_LIBRARY)
diff --git a/voice_processing/voice_processing.c b/voice_processing/voice_processing.c
index d2b4acb..8c6e7fc 100644
--- a/voice_processing/voice_processing.c
+++ b/voice_processing/voice_processing.c
@@ -18,6 +18,8 @@
 /*#define LOG_NDEBUG 0*/
 #include <stdlib.h>
 #include <dlfcn.h>
+#include <unistd.h>
+
 #include <cutils/log.h>
 #include <cutils/list.h>
 #include <hardware/audio_effect.h>