Merge "hal: fix direct output flag test in open_output_stream"
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 8601a7e..626643c 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -214,7 +214,8 @@
             snprintf(name, MAX_PATH, TZ_TYPE, tzn);
             ALOGD("Opening %s\n", name);
             read_line_from_file(name, buf, sizeof(buf));
-            buf[strlen(buf)] = '\0';
+            if (strlen(buf) > 0)
+                buf[strlen(buf) - 1] = '\0';
             if (!strcmp(buf, sensor_name)) {
                 found = 1;
                 break;
diff --git a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
index 4cfee1b..6154e0c 100644
--- a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
+++ b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
@@ -4070,6 +4070,8 @@
     //The total length of the data to be transcoded
     srcStart = buffer->pBuffer;
     OMX_U8 *data = NULL;
+    ssize_t bytes = 0;
+
     PrintFrameHdr(OMX_COMPONENT_GENERATE_ETB,buffer);
     memset(&meta_in,0,sizeof(meta_in));
     if ( search_input_bufhdr(buffer) == false )
@@ -4104,7 +4106,22 @@
     }
 
     memcpy(&data[sizeof(META_IN)],buffer->pBuffer,buffer->nFilledLen);
-    write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
+    bytes = write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
+    if (bytes <= 0) {
+        frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+
+        if (errno == ENETRESET)
+        {
+            ALOGE("In SSR, return error to close the session");
+            m_cb.EventHandler(&m_cmp,
+                  m_app_data,
+                  OMX_EventError,
+                  OMX_ErrorHardware,
+                  0, NULL );
+        }
+        return OMX_ErrorNone;
+    }
+
     pthread_mutex_lock(&m_state_lock);
     get_state(&m_cmp, &state);
     pthread_mutex_unlock(&m_state_lock);
diff --git a/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp b/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp
index 8200365..af9f785 100644
--- a/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp
+++ b/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp
@@ -3974,6 +3974,8 @@
     //The total length of the data to be transcoded
     srcStart = buffer->pBuffer;
     OMX_U8 *data = NULL;
+    ssize_t bytes = 0;
+
     PrintFrameHdr(OMX_COMPONENT_GENERATE_ETB,buffer);
     memset(&meta_in,0,sizeof(meta_in));
     if ( search_input_bufhdr(buffer) == false )
@@ -4003,7 +4005,21 @@
     }
 
     memcpy(&data[sizeof(META_IN)],buffer->pBuffer,buffer->nFilledLen);
-    write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
+    bytes = write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
+    if (bytes <= 0) {
+        frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+
+        if (errno == ENETRESET)
+        {
+            ALOGE("In SSR, return error to close the session");
+            m_cb.EventHandler(&m_cmp,
+                  m_app_data,
+                  OMX_EventError,
+                  OMX_ErrorHardware,
+                  0, NULL );
+        }
+        return OMX_ErrorNone;
+    }
 
     pthread_mutex_lock(&m_state_lock);
     get_state(&m_cmp, &state);
@@ -4045,11 +4061,21 @@
                          buffer->nAllocLen,buffer->pBuffer,
                          nReadbytes,nNumOutputBuf);
       if (nReadbytes <= 0) {
-                  buffer->nFilledLen = 0;
+            buffer->nFilledLen = 0;
             buffer->nOffset = 0;
-                buffer->nTimeStamp = nTimestamp;
-             frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
-                  return OMX_ErrorNone;
+            buffer->nTimeStamp = nTimestamp;
+            frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+
+            if (errno == ENETRESET)
+            {
+                ALOGE("In SSR, return error to close the session");
+                m_cb.EventHandler(&m_cmp,
+                   m_app_data,
+                   OMX_EventError,
+                   OMX_ErrorHardware,
+                   0, NULL );
+            }
+            return OMX_ErrorNone;
       } else
               DEBUG_PRINT("Read bytes %d\n",nReadbytes);
       // Buffer from Driver will have
diff --git a/mm-audio/aenc-qcelp13/qdsp6/src/omx_qcelp13_aenc.cpp b/mm-audio/aenc-qcelp13/qdsp6/src/omx_qcelp13_aenc.cpp
index 399b8cf..d25eb7f 100644
--- a/mm-audio/aenc-qcelp13/qdsp6/src/omx_qcelp13_aenc.cpp
+++ b/mm-audio/aenc-qcelp13/qdsp6/src/omx_qcelp13_aenc.cpp
@@ -3972,6 +3972,8 @@
     //The total length of the data to be transcoded
     srcStart = buffer->pBuffer;
     OMX_U8 *data = NULL;
+    ssize_t bytes = 0;
+
     PrintFrameHdr(OMX_COMPONENT_GENERATE_ETB,buffer);
     memset(&meta_in,0,sizeof(meta_in));
     if ( search_input_bufhdr(buffer) == false )
@@ -4001,7 +4003,21 @@
     }
 
     memcpy(&data[sizeof(META_IN)],buffer->pBuffer,buffer->nFilledLen);
-    write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
+    bytes = write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
+    if (bytes <= 0) {
+        frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+
+        if (errno == ENETRESET)
+        {
+            ALOGE("In SSR, return error to close the session");
+            m_cb.EventHandler(&m_cmp,
+                  m_app_data,
+                  OMX_EventError,
+                  OMX_ErrorHardware,
+                  0, NULL );
+        }
+        return OMX_ErrorNone;
+    }
 
     pthread_mutex_lock(&m_state_lock);
     get_state(&m_cmp, &state);
@@ -4043,11 +4059,21 @@
                          buffer->nAllocLen,buffer->pBuffer,
                          nReadbytes,nNumOutputBuf);
       if (nReadbytes <= 0) {
-                  buffer->nFilledLen = 0;
+            buffer->nFilledLen = 0;
             buffer->nOffset = 0;
-                buffer->nTimeStamp = nTimestamp;
-             frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
-                  return OMX_ErrorNone;
+            buffer->nTimeStamp = nTimestamp;
+            frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+
+            if (errno == ENETRESET)
+            {
+                ALOGE("In SSR, return error to close the session");
+                m_cb.EventHandler(&m_cmp,
+                   m_app_data,
+                   OMX_EventError,
+                   OMX_ErrorHardware,
+                   0, NULL );
+            }
+            return OMX_ErrorNone;
       } else
               DEBUG_PRINT("Read bytes %d\n",nReadbytes);
 
diff --git a/post_proc/reverb.c b/post_proc/reverb.c
index b256e53..450ce81 100644
--- a/post_proc/reverb.c
+++ b/post_proc/reverb.c
@@ -281,17 +281,19 @@
     context->next_preset = preset;
     offload_reverb_set_preset(&(context->offload_reverb), preset);
 
-    enable = (preset == REVERB_PRESET_NONE) ? false: true;
-    offload_reverb_set_enable_flag(&(context->offload_reverb), enable);
+    if (context->enabled_by_client) {
+        enable = (preset == REVERB_PRESET_NONE) ? false: true;
+        offload_reverb_set_enable_flag(&(context->offload_reverb), enable);
 
-    if (context->ctl)
-        offload_reverb_send_params(context->ctl, &context->offload_reverb,
+        if (context->ctl)
+            offload_reverb_send_params(context->ctl, &context->offload_reverb,
                                    OFFLOAD_SEND_REVERB_ENABLE_FLAG |
                                    OFFLOAD_SEND_REVERB_PRESET);
-    if (context->hw_acc_fd > 0)
-        hw_acc_reverb_send_params(context->hw_acc_fd, &context->offload_reverb,
+        if (context->hw_acc_fd > 0)
+            hw_acc_reverb_send_params(context->hw_acc_fd, &context->offload_reverb,
                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
                                   OFFLOAD_SEND_REVERB_PRESET);
+    }
 }
 
 void reverb_set_all_properties(reverb_context_t *context,
@@ -600,6 +602,7 @@
     set_config(context, &context->config);
 
     reverb_ctxt->hw_acc_fd = -1;
+    reverb_ctxt->enabled_by_client = false;
     memset(&(reverb_ctxt->reverb_settings), 0, sizeof(reverb_settings_t));
     memset(&(reverb_ctxt->offload_reverb), 0, sizeof(struct reverb_params));
 
@@ -615,6 +618,16 @@
     reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
 
     ALOGV("%s: ctxt %p", __func__, reverb_ctxt);
+    reverb_ctxt->enabled_by_client = true;
+
+    /* REVERB_PRESET_NONE is equivalent to disabled state,
+     * But support for this state is not provided in DSP.
+     * Hence, do not set enable flag, if in peset mode with preset "NONE".
+     * Effect would be enabled when valid preset is set.
+     */
+    if ((reverb_ctxt->preset == true) &&
+        (reverb_ctxt->next_preset == REVERB_PRESET_NONE))
+        return 0;
 
     if (!offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb)))
         offload_reverb_set_enable_flag(&(reverb_ctxt->offload_reverb), true);
@@ -626,6 +639,7 @@
     reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
 
     ALOGV("%s: ctxt %p", __func__, reverb_ctxt);
+    reverb_ctxt->enabled_by_client = false;
     if (offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb))) {
         offload_reverb_set_enable_flag(&(reverb_ctxt->offload_reverb), false);
         if (reverb_ctxt->ctl)
diff --git a/post_proc/reverb.h b/post_proc/reverb.h
index 991151e..1a5ca0d 100644
--- a/post_proc/reverb.h
+++ b/post_proc/reverb.h
@@ -48,6 +48,7 @@
     // Offload vars
     struct mixer_ctl *ctl;
     int hw_acc_fd;
+    bool enabled_by_client;
     bool auxiliary;
     bool preset;
     uint16_t cur_preset;
diff --git a/post_proc/virtualizer.c b/post_proc/virtualizer.c
index 2748568..3874f0b 100644
--- a/post_proc/virtualizer.c
+++ b/post_proc/virtualizer.c
@@ -56,6 +56,15 @@
     ALOGV("%s: ctxt %p, strength: %d", __func__, context, strength);
     context->strength = strength;
 
+    /*
+     *  Zero strength is not equivalent to disable state as down mix
+     *  is still happening for multichannel inputs.
+     *  For better user experience, explicitly disable virtualizer module
+     *  when strength is 0.
+     */
+    offload_virtualizer_set_enable_flag(&(context->offload_virt),
+                                        ((strength > 0) && !(context->temp_disabled)) ?
+                                        true : false);
     offload_virtualizer_set_strength(&(context->offload_virt), strength);
     if (context->ctl)
         offload_virtualizer_send_params(context->ctl, &context->offload_virt,