Merge "post_proc: Audiosphere SA+ concurrency implementation"
diff --git a/hal/Android.mk b/hal/Android.mk
index d7b7c50..f83faa5 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -231,10 +231,6 @@
     LOCAL_SRC_FILES += audio_extn/source_track.c
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUDIOSPHERE)),true)
-    LOCAL_CFLAGS += -DAUDIOSPHERE_ENABLED
-endif
-
 LOCAL_SHARED_LIBRARIES := \
 	liblog \
 	libcutils \
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 34da4fe..061af81 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -81,8 +81,6 @@
 /* Query offload playback instances count */
 #define AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE "offload_num_active"
 #define AUDIO_PARAMETER_HPX            "HPX"
-#define AUDIO_PARAMETER_KEY_ASPHERE_ENABLE   "asphere_enable"
-#define AUDIO_PARAMETER_KEY_ASPHERE_STRENGTH "asphere_strength"
 
 #ifndef FM_ENABLED
 #define audio_extn_fm_set_parameters(adev, parms) (0)
@@ -558,103 +556,6 @@
     return ret;
 }
 
-#ifndef AUDIOSPHERE_ENABLED
-#define audio_extn_asphere_set_parameters(adev, parms)  (0)
-#define audio_extn_asphere_get_parameters(adev, query, reply) (0)
-#else
-int32_t audio_extn_asphere_set_parameters(const struct audio_device *adev,
-                                     struct str_parms *parms)
-{
-    int ret = 0, val[2];
-    char value[32] = {0};
-    int set_enable, set_strength;
-    int enable = -1, strength = -1;
-    struct mixer_ctl *ctl = NULL;
-    const char *mixer_ctl_name = "MSM ASphere Set Param";
-    char propValue[PROPERTY_VALUE_MAX] = {0};
-    bool asphere_prop_enabled = false;
-
-    if (property_get("audio.pp.asphere.enabled", propValue, "false")) {
-        if (!strncmp("true", propValue, 4))
-            asphere_prop_enabled = true;
-    }
-
-    if (!asphere_prop_enabled) {
-        ALOGV("%s: property not set!!! not doing anything", __func__);
-        return ret;
-    }
-
-    set_enable = str_parms_get_str(parms,
-                            AUDIO_PARAMETER_KEY_ASPHERE_ENABLE,
-                            value, sizeof(value));
-    if (set_enable > 0)
-        enable = atoi(value);
-
-    set_strength = str_parms_get_str(parms,
-                            AUDIO_PARAMETER_KEY_ASPHERE_STRENGTH,
-                            value, sizeof(value));
-    if (set_strength > 0)
-        strength = atoi(value);
-
-    if (set_enable >= 0 || set_strength >= 0) {
-        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-        if (!ctl) {
-            ALOGE("%s: could not get ctl for mixer cmd - %s",
-                  __func__, mixer_ctl_name);
-            return -EINVAL;
-        }
-        ALOGD("%s: set ctl \"%s:%d,%d\"",
-              __func__, mixer_ctl_name, enable, strength);
-        val[0] = enable;
-        val[1] = strength;
-        ret = mixer_ctl_set_array(ctl, val, sizeof(val)/sizeof(val[0]));
-        if (ret)
-            ALOGE("%s: set ctl failed!!!\"%s:%d,%d\"",
-                  __func__, mixer_ctl_name, enable, strength);
-    }
-    ALOGV("%s: exit ret %d", __func__, ret);
-    return ret;
-}
-
-int32_t audio_extn_asphere_get_parameters(const struct audio_device *adev,
-                                          struct str_parms *query,
-                                          struct str_parms *reply)
-{
-    int ret = 0, val[2] = {-1, -1};
-    char value[32] = {0};
-    int get_enable, get_strength;
-    struct mixer_ctl *ctl = NULL;
-    const char *mixer_ctl_name = "MSM ASphere Set Param";
-
-    get_enable = str_parms_get_str(query,
-                                   AUDIO_PARAMETER_KEY_ASPHERE_ENABLE,
-                                   value, sizeof(value));
-    get_strength = str_parms_get_str(query,
-                                     AUDIO_PARAMETER_KEY_ASPHERE_STRENGTH,
-                                     value, sizeof(value));
-    if (get_enable > 0 || get_strength > 0) {
-        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-        if (!ctl) {
-            ALOGE("%s: could not get ctl for mixer cmd - %s",
-                  __func__, mixer_ctl_name);
-            return -EINVAL;
-        }
-        ret = mixer_ctl_get_array(ctl, val, sizeof(val)/sizeof(val[0]));
-        if (ret)
-            ALOGE("%s: got ctl failed!!! \"%s:%d,%d\"",
-                   __func__, mixer_ctl_name, val[0], val[1]);
-        if (get_enable > 0)
-            str_parms_add_int(reply,
-                              AUDIO_PARAMETER_KEY_ASPHERE_ENABLE, val[0]);
-        if (get_strength > 0)
-            str_parms_add_int(reply,
-                              AUDIO_PARAMETER_KEY_ASPHERE_STRENGTH, val[1]);
-    }
-    ALOGV("%s: exit ret %d", __func__, ret);
-    return ret;
-}
-#endif
-
 void audio_extn_set_parameters(struct audio_device *adev,
                                struct str_parms *parms)
 {
@@ -672,7 +573,8 @@
    audio_extn_hpx_set_parameters(adev, parms);
    audio_extn_pm_set_parameters(parms);
    audio_extn_source_track_set_parameters(adev, parms);
-   audio_extn_asphere_set_parameters(adev, parms);
+   if (adev->offload_effects_set_parameters != NULL)
+       adev->offload_effects_set_parameters(parms);
 }
 
 void audio_extn_get_parameters(const struct audio_device *adev,
@@ -686,7 +588,8 @@
     audio_extn_dts_eagle_get_parameters(adev, query, reply);
     audio_extn_hpx_get_parameters(query, reply);
     audio_extn_source_track_get_parameters(adev, query, reply);
-    audio_extn_asphere_get_parameters(adev, query, reply);
+    if (adev->offload_effects_get_parameters != NULL)
+        adev->offload_effects_get_parameters(query, reply);
 
     kv_pairs = str_parms_to_str(reply);
     ALOGD_IF(kv_pairs != NULL, "%s: returns %s", __func__, kv_pairs);
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 37125f7..e4c8cad 100755
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3737,6 +3737,13 @@
             adev->offload_effects_set_hpx_state =
                         (int (*)(bool))dlsym(adev->offload_effects_lib,
                                          "offload_effects_bundle_set_hpx_state");
+            adev->offload_effects_get_parameters =
+                        (void (*)(struct str_parms *, struct str_parms *))
+                                         dlsym(adev->offload_effects_lib,
+                                         "offload_effects_bundle_get_parameters");
+            adev->offload_effects_set_parameters =
+                        (void (*)(struct str_parms *))dlsym(adev->offload_effects_lib,
+                                         "offload_effects_bundle_set_parameters");
         }
     }
 
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 45e90b7..f01d38d 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -323,6 +323,9 @@
 
     struct sound_card_status snd_card_status;
     int (*offload_effects_set_hpx_state)(bool);
+    void (*offload_effects_get_parameters)(struct str_parms *,
+                                           struct str_parms *);
+    void (*offload_effects_set_parameters)(struct str_parms *);
 };
 
 int select_devices(struct audio_device *adev,
diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index d5a362a..4385f1a 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -51,6 +51,14 @@
     LOCAL_CFLAGS += -DAAC_ADTS_OFFLOAD_ENABLED
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_SPK)),true)
+LOCAL_CFLAGS += -DAUDIO_EXTN_HDMI_SPK_ENABLED
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
+LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
+endif
+
 LOCAL_MODULE := libaudiopolicymanager
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index d8d90ce..a638c1d 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -122,6 +122,15 @@
         // handle output device connection
         case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
             if (index >= 0) {
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+                if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                   if (!strncmp(device_address, "hdmi_spkr", 9)) {
+                        mHdmiAudioDisabled = false;
+                    } else {
+                        mHdmiAudioEvent = true;
+                    }
+                }
+#endif
                 ALOGW("setDeviceConnectionState() device already connected: %x", device);
                 return INVALID_OPERATION;
             }
@@ -129,6 +138,20 @@
 
             // register new device as available
             index = mAvailableOutputDevices.add(devDesc);
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+            if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                if (!strncmp(device_address, "hdmi_spkr", 9)) {
+                    mHdmiAudioDisabled = false;
+                } else {
+                    mHdmiAudioEvent = true;
+                }
+                if (mHdmiAudioDisabled || !mHdmiAudioEvent) {
+                    mAvailableOutputDevices.remove(devDesc);
+                    ALOGW("HDMI sink not connected, do not route audio to HDMI out");
+                    return INVALID_OPERATION;
+                }
+            }
+#endif
             if (index >= 0) {
                 sp<HwModule> module = mHwModules.getModuleForDevice(device);
                 if (module == 0) {
@@ -164,6 +187,15 @@
         // handle output device disconnection
         case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
             if (index < 0) {
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+                if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                    if (!strncmp(device_address, "hdmi_spkr", 9)) {
+                        mHdmiAudioDisabled = true;
+                    } else {
+                        mHdmiAudioEvent = false;
+                    }
+                }
+#endif
                 ALOGW("setDeviceConnectionState() device not connected: %x", device);
                 return INVALID_OPERATION;
             }
@@ -177,7 +209,15 @@
 
             // remove device from available output devices
             mAvailableOutputDevices.remove(devDesc);
-
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+            if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                if (!strncmp(device_address, "hdmi_spkr", 9)) {
+                    mHdmiAudioDisabled = true;
+                } else {
+                    mHdmiAudioEvent = false;
+                }
+            }
+#endif
             checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
 
             // Propagate device availability to Engine
@@ -524,9 +564,8 @@
                 (isStrategyActive(mPrimaryOutput,STRATEGY_SONIFICATION)
                 && (!isStrategyActive(mPrimaryOutput,STRATEGY_MEDIA)))) {
         device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)||
-                (isStrategyActive(mPrimaryOutput,STRATEGY_SONIFICATION_RESPECTFUL)
-                && (!isStrategyActive(mPrimaryOutput, STRATEGY_MEDIA)))) {
+    } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL) ||
+                isStrategyActive(mPrimaryOutput,STRATEGY_SONIFICATION_RESPECTFUL)) {
         device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
     } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
         device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
@@ -547,6 +586,7 @@
 {
     ALOGV("setPhoneState() state %d", state);
     // store previous phone state for management of sonification strategy below
+    audio_devices_t newDevice = AUDIO_DEVICE_NONE;
     int oldState = mEngine->getPhoneState();
 
     if (mEngine->setPhoneState(state) != NO_ERROR) {
@@ -564,8 +604,7 @@
                 if (stream == AUDIO_STREAM_PATCH) {
                     continue;
                 }
-
-            handleIncallSonification((audio_stream_type_t)stream, false, true, curOutput);
+                handleIncallSonification((audio_stream_type_t)stream, false, true, curOutput);
             }
         }
 
@@ -837,7 +876,14 @@
             setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
         }
     }
-
+    //update device for all non-primary outputs
+    for (size_t i = 0; i < mOutputs.size(); i++) {
+        audio_io_handle_t output = mOutputs.keyAt(i);
+        if (output != mPrimaryOutput->mIoHandle) {
+            newDevice = getNewOutputDevice(mOutputs.valueFor(output), false /*fromCache*/);
+            setOutputDevice(mOutputs.valueFor(output), newDevice, (newDevice != AUDIO_DEVICE_NONE));
+        }
+    }
     // if entering in call state, handle special case of active streams
     // pertaining to sonification strategy see handleIncallSonification()
     if (isStateInCall(state)) {
@@ -848,7 +894,7 @@
                if (stream == AUDIO_STREAM_PATCH) {
                     continue;
                 }
-            handleIncallSonification((audio_stream_type_t)stream, true, true, curOutput);
+                handleIncallSonification((audio_stream_type_t)stream, true, true, curOutput);
            }
         }
     }
@@ -869,10 +915,10 @@
     handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
 
     // handle special case for sonification while in call
-    if (isInCall()) {
+    if (isInCall() && (outputDesc->mRefCount[stream] == 1)) {
         if (outputDesc->isDuplicated()) {
-            handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
-            handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
+            handleIncallSonification(stream, false, false, outputDesc->mOutput1->mIoHandle);
+            handleIncallSonification(stream, false, false, outputDesc->mOutput2->mIoHandle);
         }
         handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
     }
@@ -901,8 +947,9 @@
                         desc->isActive() &&
                         outputDesc->sharesHwModuleWith(desc) &&
                         (newDevice != desc->device())) {
-                    setOutputDevice(desc,
-                                    getNewOutputDevice(desc, false /*fromCache*/),
+                        audio_devices_t dev = getNewOutputDevice(mOutputs.valueFor(curOutput), false /*fromCache*/);
+                        setOutputDevice(desc,
+                                    dev,
                                     true,
                                     outputDesc->latency()*2);
                 }
@@ -1322,6 +1369,7 @@
     }
 #endif
 
+#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
     /*
     * WFD audio routes back to target speaker when starting a ringtone playback.
     * This is because primary output is reused for ringtone, so output device is
@@ -1341,6 +1389,8 @@
         else //route every thing else to ULL path
             flags = AUDIO_OUTPUT_FLAG_FAST;
     }
+#endif
+
     // open a direct output if required by specified parameters
     //force direct flag if offload flag is set: offloading implies a direct output stream
     // and all common behaviors are driven by checking only the direct flag
@@ -1669,7 +1719,7 @@
         // Move tracks associated to this strategy from previous output to new output
         for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
             // Do not call invalidate for ENFORCED_AUDIBLE (otherwise pops are seen for camcorder)
-            if ((i != AUDIO_STREAM_ENFORCED_AUDIBLE && (i != AUDIO_STREAM_PATCH)) {
+            if ((i != AUDIO_STREAM_ENFORCED_AUDIBLE && (i != AUDIO_STREAM_PATCH))) {
                ALOGD("Invalidate on releaseInput for stream :: %d ", i);
                //FIXME see fixme on name change
                mpClientInterface->invalidateStream((audio_stream_type_t)i);
@@ -1766,35 +1816,11 @@
     return status;
 }
 
-audio_devices_t AudioPolicyManagerCustom::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
-{
-    audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
-    audio_devices_t device = AUDIO_DEVICE_NONE;
-    switch (strategy) {
-        case STRATEGY_SONIFICATION:
-        case STRATEGY_ENFORCED_AUDIBLE:
-        case STRATEGY_ACCESSIBILITY:
-        case STRATEGY_REROUTING:
-        case STRATEGY_MEDIA:
-            if (strategy != STRATEGY_SONIFICATION){
-                // no sonification on WFD sink
-                device |= availableOutputDeviceTypes & AUDIO_DEVICE_OUT_PROXY;
-                if (device != AUDIO_DEVICE_NONE) {
-                    ALOGV("Found proxy for strategy %d", strategy);
-                    return device;
-                }
-            }
-            break;
-        default:
-            ALOGV("getDeviceForStrategy() unknown strategy: %d", strategy);
-            break;
-    }
-    device = AudioPolicyManager::getDeviceForStrategy(strategy, fromCache);
-    return device;
-}
-
 AudioPolicyManagerCustom::AudioPolicyManagerCustom(AudioPolicyClientInterface *clientInterface)
-    : AudioPolicyManager(clientInterface)
+    : AudioPolicyManager(clientInterface),
+      mHdmiAudioDisabled(false),
+      mHdmiAudioEvent(false),
+      mPrevPhoneState(0)
 {
 
     for (size_t i = 0; i < mHwModules.size(); i++) {
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index fdb6f82..53c9a1b 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -36,7 +36,7 @@
 #define AUDIO_FORMAT_AAC_ADTS 0x1E000000UL
 #endif
 
-#ifndef AFE_PROXY_ENABLED
+#ifndef AUDIO_EXTN_AFE_PROXY_ENABLED
 #define AUDIO_DEVICE_OUT_PROXY 0x1000000
 #endif
 // ----------------------------------------------------------------------------
@@ -55,7 +55,6 @@
                                           const char *device_name);
         virtual void setPhoneState(audio_mode_t state);
 
-
         virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
 
         virtual status_t getInputForAttr(const audio_attributes_t *attr,
@@ -75,7 +74,6 @@
         virtual status_t stopInput(audio_io_handle_t input,
                                    audio_session_t session);
 
-        virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy, bool fromCache);
 protected:
 
          status_t checkAndSetVolume(audio_stream_type_t stream,
@@ -102,9 +100,9 @@
          status_t stopSource(sp<SwAudioOutputDescriptor> outputDesc,
                             audio_stream_type_t stream,
                             bool forceDeviceUpdate);
-        // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON   313
-        // returns 0 if no mute/unmute event happened, the largest latency of the device where   314
-        //   the mute/unmute happened 315
+        // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
+        // returns 0 if no mute/unmute event happened, the largest latency of the device where
+        //   the mute/unmute happened
         uint32_t handleEventForBeacon(int){return 0;}
         uint32_t setBeaconMute(bool){return 0;}
 #ifdef VOICE_CONCURRENCY
@@ -120,14 +118,9 @@
         //parameter indicates if HDMI plug in/out detected
         bool mHdmiAudioEvent;
 private:
-        static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
-                int indexInUi);
         // updates device caching and output for streams that can influence the
         //    routing of notifications
         void handleNotificationRoutingForStream(audio_stream_type_t stream);
-        static bool isVirtualInputDevice(audio_devices_t device);
-        static bool deviceDistinguishesOnAddress(audio_devices_t device);
-        uint32_t nextUniqueId();
         // internal method to return the output handle for the given device and format
         audio_io_handle_t getOutputForDevice(
                 audio_devices_t device,
@@ -145,8 +138,6 @@
         // Used for record + playback concurrency
         bool mIsInputRequestOnProgress;
 #endif
-
-
 };
 
 };