Merge "HAL: Identify Track offload session"
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index a114b30..5b18e37 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -579,11 +579,12 @@
 
     if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out == NULL)) {
         sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-        app_type_cfg[len++] = platform_get_default_app_type(adev->platform);
+        app_type_cfg[len++] = platform_get_default_app_type_v2(adev->platform, usecase->type);
         app_type_cfg[len++] = acdb_dev_id;
         app_type_cfg[len++] = sample_rate;
         ALOGI("%s PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
-              __func__, platform_get_default_app_type(adev->platform), acdb_dev_id, sample_rate);
+              __func__, platform_get_default_app_type_v2(adev->platform, usecase->type),
+              acdb_dev_id, sample_rate);
     } else if (usecase->type == PCM_PLAYBACK) {
         if ((24 == usecase->stream.out->bit_width) &&
             (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
@@ -609,11 +610,12 @@
         ALOGI("%s PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
               __func__, usecase->stream.out->app_type_cfg.app_type, acdb_dev_id, sample_rate);
     } else if (usecase->type == PCM_CAPTURE) {
-        app_type_cfg[len++] = platform_get_default_app_type(adev->platform);
+        app_type_cfg[len++] = platform_get_default_app_type_v2(adev->platform, usecase->type);
         app_type_cfg[len++] = acdb_dev_id;
         app_type_cfg[len++] = sample_rate;
         ALOGI("%s CAPTURE app_type %d, acdb_dev_id %d, sample_rate %d",
-           __func__, platform_get_default_app_type(adev->platform), acdb_dev_id, sample_rate);
+           __func__, platform_get_default_app_type_v2(adev->platform, usecase->type),
+           acdb_dev_id, sample_rate);
     }
     mixer_ctl_set_array(ctl, app_type_cfg, len);
     rc = 0;
@@ -638,8 +640,8 @@
     if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE)) {
         /* when app type is default. the sample rate is not used to send cal */
         platform_send_audio_calibration(adev->platform, usecase,
-                                        platform_get_default_app_type(adev->platform),
-                                        48000);
+                 platform_get_default_app_type_v2(adev->platform, usecase->type),
+                 48000);
     }
 }
 
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 44ee73a..54ac5f6 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1928,6 +1928,14 @@
         return DEFAULT_APP_TYPE;
 }
 
+int platform_get_default_app_type_v2(void *platform, usecase_type_t  type)
+{
+    if(type == PCM_CAPTURE)
+        return DEFAULT_APP_TYPE_TX_PATH;
+    else
+        return DEFAULT_APP_TYPE_RX_PATH;
+}
+
 int platform_get_snd_device_acdb_id(snd_device_t snd_device)
 {
     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 0af5a08..59aae10 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -99,7 +99,8 @@
 #define EDID_FORMAT_LPCM    1
 
 /* fallback app type if the default app type from acdb loader fails */
-#define DEFAULT_APP_TYPE  0x11130
+#define DEFAULT_APP_TYPE_RX_PATH  0x11130
+#define DEFAULT_APP_TYPE_TX_PATH  0x11132
 
 /* Retry for delay in FW loading*/
 #define RETRY_NUMBER 10
@@ -1822,7 +1823,15 @@
     if (my_data->acdb_get_default_app_type)
         return my_data->acdb_get_default_app_type();
     else
-        return DEFAULT_APP_TYPE;
+        return DEFAULT_APP_TYPE_RX_PATH;
+}
+
+int platform_get_default_app_type_v2(void *platform, usecase_type_t  type)
+{
+    if(type == PCM_CAPTURE)
+        return DEFAULT_APP_TYPE_TX_PATH;
+    else
+        return DEFAULT_APP_TYPE_RX_PATH;
 }
 
 int platform_get_snd_device_acdb_id(snd_device_t snd_device)
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 3ab5191..a89c267 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -46,6 +46,7 @@
 int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
                                     int app_type, int sample_rate);
 int platform_get_default_app_type(void *platform);
+int platform_get_default_app_type_v2(void *platform, usecase_type_t  type);
 int platform_switch_voice_call_device_pre(void *platform);
 int platform_switch_voice_call_enable_device_config(void *platform,
                                                     snd_device_t out_snd_device,
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 77bf0e1..29bb883 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -15,6 +15,24 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ *  (C) 2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 #define LOG_TAG "AudioPolicyManagerCustom"
@@ -46,6 +64,9 @@
 #include <soundtrigger/SoundTrigger.h>
 #include "AudioPolicyManager.h"
 #include <policy.h>
+#ifdef DOLBY_ENABLE
+#include "DolbyAudioPolicy_impl.h"
+#endif // DOLBY_END
 
 namespace android {
 #ifdef VOICE_CONCURRENCY
@@ -246,6 +267,11 @@
         }
 
         updateDevicesAndOutputs();
+#ifdef DOLBY_ENABLE
+        // Before closing the opened outputs, update endpoint property with device capabilities
+        audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AUDIO_STREAM_MUSIC), true);
+        mDolbyAudioPolicy.setEndpointSystemProperty(audioOutputDevice, mHwModules);
+#endif // DOLBY_END
         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
             audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
             updateCallRouting(newDevice);
@@ -1691,7 +1717,23 @@
         addOutput(output, outputDesc);
         audio_io_handle_t dstOutput = getOutputForEffect();
         if (dstOutput == output) {
+#ifdef DOLBY_ENABLE
+            status_t status = mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
+            if (status == NO_ERROR) {
+                for (size_t i = 0; i < mEffects.size(); i++) {
+                    sp<EffectDescriptor> desc = mEffects.valueAt(i);
+                    if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX) {
+                        // update the mIo member of EffectDescriptor for the global effect
+                        ALOGV("%s updating mIo", __FUNCTION__);
+                        desc->mIo = dstOutput;
+                    }
+                }
+            } else {
+                ALOGW("%s moveEffects from %d to %d failed", __FUNCTION__, srcOutput, dstOutput);
+            }
+#else // DOLBY_END
             mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
+#endif // LINE_ADDED_BY_DOLBY
         }
         mPreviousOutputs = mOutputs;
         ALOGV("getOutput() returns new direct output %d", output);
diff --git a/post_proc/reverb.c b/post_proc/reverb.c
index 450ce81..2e97f68 100644
--- a/post_proc/reverb.c
+++ b/post_proc/reverb.c
@@ -230,6 +230,72 @@
                                   OFFLOAD_SEND_REVERB_LEVEL);
 }
 
+uint32_t reverb_get_reverb_delay(reverb_context_t *context)
+{
+    ALOGV("%s: ctxt %p, reverb delay: %d", __func__, context,
+                          context->reverb_settings.reverbDelay);
+    return context->reverb_settings.reverbDelay;
+}
+
+void reverb_set_reverb_delay(reverb_context_t *context, uint32_t delay)
+{
+    ALOGV("%s: ctxt %p, reverb delay: %d", __func__, context, delay);
+    context->reverb_settings.reverbDelay = delay;
+    offload_reverb_set_delay(&(context->offload_reverb), delay);
+    if (context->ctl)
+        offload_reverb_send_params(context->ctl, &context->offload_reverb,
+                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+                                   OFFLOAD_SEND_REVERB_DELAY);
+    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_DELAY);
+}
+
+int16_t reverb_get_reflections_level(reverb_context_t *context)
+{
+    ALOGV("%s: ctxt %p, reflection level: %d", __func__, context,
+                          context->reverb_settings.reflectionsLevel);
+    return context->reverb_settings.reflectionsLevel;
+}
+
+void reverb_set_reflections_level(reverb_context_t *context, int16_t level)
+{
+    ALOGV("%s: ctxt %p, reflection level: %d", __func__, context, level);
+    context->reverb_settings.reflectionsLevel = level;
+    offload_reverb_set_reflections_level(&(context->offload_reverb), level);
+    if (context->ctl)
+        offload_reverb_send_params(context->ctl, &context->offload_reverb,
+                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+                                   OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL);
+    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_REFLECTIONS_LEVEL);
+}
+
+uint32_t reverb_get_reflections_delay(reverb_context_t *context)
+{
+    ALOGV("%s: ctxt %p, reflection delay: %d", __func__, context,
+                          context->reverb_settings.reflectionsDelay);
+    return context->reverb_settings.reflectionsDelay;
+}
+
+void reverb_set_reflections_delay(reverb_context_t *context, uint32_t delay)
+{
+    ALOGV("%s: ctxt %p, reflection delay: %d", __func__, context, delay);
+    context->reverb_settings.reflectionsDelay = delay;
+    offload_reverb_set_reflections_delay(&(context->offload_reverb), delay);
+    if (context->ctl)
+        offload_reverb_send_params(context->ctl, &context->offload_reverb,
+                                   OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+                                   OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY);
+    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_REFLECTIONS_DELAY);
+}
+
 int16_t reverb_get_diffusion(reverb_context_t *context)
 {
     ALOGV("%s: ctxt %p, diffusion: %d", __func__, context,
@@ -305,8 +371,33 @@
     context->reverb_settings.decayTime = reverb_settings->decayTime;
     context->reverb_settings.decayHFRatio = reverb_settings->decayHFRatio;
     context->reverb_settings.reverbLevel = reverb_settings->reverbLevel;
+    context->reverb_settings.reverbDelay = reverb_settings->reverbDelay;
+    context->reverb_settings.reflectionsLevel = reverb_settings->reflectionsLevel;
+    context->reverb_settings.reflectionsDelay = reverb_settings->reflectionsDelay;
     context->reverb_settings.diffusion = reverb_settings->diffusion;
     context->reverb_settings.density = reverb_settings->density;
+
+    offload_reverb_set_room_level(&(context->offload_reverb),
+                               reverb_settings->roomLevel);
+    offload_reverb_set_room_hf_level(&(context->offload_reverb),
+                               reverb_settings->roomHFLevel);
+    offload_reverb_set_decay_time(&(context->offload_reverb),
+                               reverb_settings->decayTime);
+    offload_reverb_set_decay_hf_ratio(&(context->offload_reverb),
+                               reverb_settings->decayHFRatio);
+    offload_reverb_set_reverb_level(&(context->offload_reverb),
+                               reverb_settings->reverbLevel);
+    offload_reverb_set_delay(&(context->offload_reverb),
+                               reverb_settings->reverbDelay);
+    offload_reverb_set_reflections_level(&(context->offload_reverb),
+                               reverb_settings->reflectionsLevel);
+    offload_reverb_set_reflections_delay(&(context->offload_reverb),
+                               reverb_settings->reflectionsDelay);
+    offload_reverb_set_diffusion(&(context->offload_reverb),
+                               reverb_settings->diffusion);
+    offload_reverb_set_density(&(context->offload_reverb),
+                               reverb_settings->density);
+
     if (context->ctl)
         offload_reverb_send_params(context->ctl, &context->offload_reverb,
                                    OFFLOAD_SEND_REVERB_ENABLE_FLAG |
@@ -315,6 +406,9 @@
                                    OFFLOAD_SEND_REVERB_DECAY_TIME |
                                    OFFLOAD_SEND_REVERB_DECAY_HF_RATIO |
                                    OFFLOAD_SEND_REVERB_LEVEL |
+                                   OFFLOAD_SEND_REVERB_DELAY |
+                                   OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL |
+                                   OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY |
                                    OFFLOAD_SEND_REVERB_DIFFUSION |
                                    OFFLOAD_SEND_REVERB_DENSITY);
     if (context->hw_acc_fd > 0)
@@ -325,6 +419,9 @@
                                   OFFLOAD_SEND_REVERB_DECAY_TIME |
                                   OFFLOAD_SEND_REVERB_DECAY_HF_RATIO |
                                   OFFLOAD_SEND_REVERB_LEVEL |
+                                  OFFLOAD_SEND_REVERB_DELAY |
+                                  OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL |
+                                  OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY |
                                   OFFLOAD_SEND_REVERB_DIFFUSION |
                                   OFFLOAD_SEND_REVERB_DENSITY);
 }
@@ -388,16 +485,6 @@
            p->status = -EINVAL;
         p->vsize = sizeof(uint16_t);
         break;
-    case REVERB_PARAM_REFLECTIONS_LEVEL:
-        if (p->vsize < sizeof(uint16_t))
-           p->status = -EINVAL;
-        p->vsize = sizeof(uint16_t);
-        break;
-    case REVERB_PARAM_REFLECTIONS_DELAY:
-        if (p->vsize < sizeof(uint32_t))
-           p->status = -EINVAL;
-        p->vsize = sizeof(uint32_t);
-        break;
     case REVERB_PARAM_REVERB_LEVEL:
         if (p->vsize < sizeof(uint16_t))
            p->status = -EINVAL;
@@ -408,6 +495,16 @@
            p->status = -EINVAL;
         p->vsize = sizeof(uint32_t);
         break;
+    case REVERB_PARAM_REFLECTIONS_LEVEL:
+        if (p->vsize < sizeof(uint16_t))
+           p->status = -EINVAL;
+        p->vsize = sizeof(uint16_t);
+        break;
+    case REVERB_PARAM_REFLECTIONS_DELAY:
+        if (p->vsize < sizeof(uint32_t))
+           p->status = -EINVAL;
+        p->vsize = sizeof(uint32_t);
+        break;
     case REVERB_PARAM_DIFFUSION:
         if (p->vsize < sizeof(uint16_t))
            p->status = -EINVAL;
@@ -433,19 +530,6 @@
         return 0;
 
     switch (param) {
-    case REVERB_PARAM_PROPERTIES:
-        reverb_settings = (reverb_settings_t *)value;
-        reverb_settings->roomLevel = reverb_get_room_level(reverb_ctxt);
-        reverb_settings->roomHFLevel = reverb_get_room_hf_level(reverb_ctxt);
-        reverb_settings->decayTime = reverb_get_decay_time(reverb_ctxt);
-        reverb_settings->decayHFRatio = reverb_get_decay_hf_ratio(reverb_ctxt);
-        reverb_settings->reflectionsLevel = 0;
-        reverb_settings->reflectionsDelay = 0;
-        reverb_settings->reverbDelay = 0;
-        reverb_settings->reverbLevel = reverb_get_reverb_level(reverb_ctxt);
-        reverb_settings->diffusion = reverb_get_diffusion(reverb_ctxt);
-        reverb_settings->density = reverb_get_density(reverb_ctxt);
-        break;
     case REVERB_PARAM_ROOM_LEVEL:
         *(int16_t *)value = reverb_get_room_level(reverb_ctxt);
         break;
@@ -461,20 +545,33 @@
     case REVERB_PARAM_REVERB_LEVEL:
         *(int16_t *)value = reverb_get_reverb_level(reverb_ctxt);
         break;
+    case REVERB_PARAM_REVERB_DELAY:
+        *(uint32_t *)value = reverb_get_reverb_delay(reverb_ctxt);
+        break;
+    case REVERB_PARAM_REFLECTIONS_LEVEL:
+        *(int16_t *)value = reverb_get_reflections_level(reverb_ctxt);
+        break;
+    case REVERB_PARAM_REFLECTIONS_DELAY:
+        *(uint32_t *)value = reverb_get_reflections_delay(reverb_ctxt);
+        break;
     case REVERB_PARAM_DIFFUSION:
         *(int16_t *)value = reverb_get_diffusion(reverb_ctxt);
         break;
     case REVERB_PARAM_DENSITY:
         *(int16_t *)value = reverb_get_density(reverb_ctxt);
         break;
-    case REVERB_PARAM_REFLECTIONS_LEVEL:
-        *(uint16_t *)value = 0;
-        break;
-    case REVERB_PARAM_REFLECTIONS_DELAY:
-        *(uint32_t *)value = 0;
-        break;
-    case REVERB_PARAM_REVERB_DELAY:
-        *(uint32_t *)value = 0;
+    case REVERB_PARAM_PROPERTIES:
+        reverb_settings = (reverb_settings_t *)value;
+        reverb_settings->roomLevel = reverb_get_room_level(reverb_ctxt);
+        reverb_settings->roomHFLevel = reverb_get_room_hf_level(reverb_ctxt);
+        reverb_settings->decayTime = reverb_get_decay_time(reverb_ctxt);
+        reverb_settings->decayHFRatio = reverb_get_decay_hf_ratio(reverb_ctxt);
+        reverb_settings->reverbLevel = reverb_get_reverb_level(reverb_ctxt);
+        reverb_settings->reverbDelay = reverb_get_reverb_delay(reverb_ctxt);
+        reverb_settings->reflectionsLevel = reverb_get_reflections_level(reverb_ctxt);
+        reverb_settings->reflectionsDelay = reverb_get_reflections_delay(reverb_ctxt);
+        reverb_settings->diffusion = reverb_get_diffusion(reverb_ctxt);
+        reverb_settings->density = reverb_get_density(reverb_ctxt);
         break;
     default:
         p->status = -EINVAL;
@@ -496,6 +593,7 @@
     int16_t level;
     int16_t ratio;
     uint32_t time;
+    uint32_t delay;
 
     ALOGV("%s: ctxt %p, param %d", __func__, reverb_ctxt, param);
 
@@ -515,6 +613,7 @@
     switch (param) {
     case REVERB_PARAM_PROPERTIES:
         reverb_settings = (reverb_settings_t *)value;
+        reverb_set_all_properties(reverb_ctxt, reverb_settings);
         break;
     case REVERB_PARAM_ROOM_LEVEL:
         level = *(int16_t *)value;
@@ -536,6 +635,18 @@
         level = *(int16_t *)value;
         reverb_set_reverb_level(reverb_ctxt, level);
         break;
+    case REVERB_PARAM_REVERB_DELAY:
+        delay = *(uint32_t *)value;
+        reverb_set_reverb_delay(reverb_ctxt, delay);
+        break;
+    case REVERB_PARAM_REFLECTIONS_LEVEL:
+        level = *(int16_t *)value;
+        reverb_set_reflections_level(reverb_ctxt, level);
+        break;
+    case REVERB_PARAM_REFLECTIONS_DELAY:
+        delay = *(uint32_t *)value;
+        reverb_set_reflections_delay(reverb_ctxt, delay);
+        break;
     case REVERB_PARAM_DIFFUSION:
         ratio = *(int16_t *)value;
         reverb_set_diffusion(reverb_ctxt, ratio);
@@ -544,10 +655,6 @@
         ratio = *(int16_t *)value;
         reverb_set_density(reverb_ctxt, ratio);
         break;
-    case REVERB_PARAM_REFLECTIONS_LEVEL:
-    case REVERB_PARAM_REFLECTIONS_DELAY:
-    case REVERB_PARAM_REVERB_DELAY:
-        break;
     default:
         p->status = -EINVAL;
         break;
diff --git a/post_proc/reverb.h b/post_proc/reverb.h
index 1a5ca0d..3bdd9af 100644
--- a/post_proc/reverb.h
+++ b/post_proc/reverb.h
@@ -40,7 +40,7 @@
     uint32_t    reverbDelay;
     int16_t     diffusion;
     int16_t     density;
-} reverb_settings_t;
+}  __attribute__((packed)) reverb_settings_t;
 
 typedef struct reverb_context_s {
     effect_context_t common;