am 6ae807c4: mm-audio: Fix delay at the start of MT voice call

* commit '6ae807c434c814a2ba6a84198a536d3a4b4153de':
  mm-audio: Fix delay at the start of MT voice call
diff --git a/alsa_sound/Android.mk b/alsa_sound/Android.mk
index 738b969..534dd6a 100644
--- a/alsa_sound/Android.mk
+++ b/alsa_sound/Android.mk
@@ -66,7 +66,6 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
-ifeq (1,0) # use default audio policy manager
 # This is the ALSA audio policy manager
 
 include $(CLEAR_VARS)
@@ -74,10 +73,6 @@
 LOCAL_CFLAGS := -D_POSIX_SOURCE
 LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
 
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
-  LOCAL_CFLAGS += -DWITH_A2DP
-endif
-
 LOCAL_SRC_FILES := \
     audio_policy_hal.cpp \
     AudioPolicyManagerALSA.cpp
@@ -88,18 +83,15 @@
 
 LOCAL_STATIC_LIBRARIES := \
     libmedia_helper \
-    libaudiohw_legacy \
     libaudiopolicy_legacy
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
-    libutils \
-    libmedia
+    libutils
 
 LOCAL_C_INCLUDES += hardware/libhardware_legacy/audio
 
 include $(BUILD_SHARED_LIBRARY)
-endif
 
 # This is the ALSA module which behaves closely like the original
 
diff --git a/alsa_sound/AudioPolicyManagerALSA.cpp b/alsa_sound/AudioPolicyManagerALSA.cpp
index 98f8203..3932a8c 100644
--- a/alsa_sound/AudioPolicyManagerALSA.cpp
+++ b/alsa_sound/AudioPolicyManagerALSA.cpp
@@ -29,9 +29,9 @@
 // AudioPolicyManagerALSA
 // ----------------------------------------------------------------------------
 
-//Compiling error seen (only) on mako-pdk project if AudioParamer doesn't exist in this file
-//No issue is seen on QCOM jb-mailine if remvong this line
-//AudioParameter param;
+//Compiling error seen if AudioParamer doesn't exist in this file
+
+AudioParameter param;
 
 // ---  class factory
 
@@ -46,4 +46,124 @@
     delete interface;
 }
 
+void AudioPolicyManager::setPhoneState(int state) {
+    ALOGV("setPhoneState() state %d", state);
+    audio_devices_t newDevice = AUDIO_DEVICE_NONE;
+    if (state < 0 || state >= AudioSystem::NUM_MODES) {
+        ALOGW("setPhoneState() invalid state %d", state);
+        return;
+    }
+
+    if (state == mPhoneState) {
+        ALOGW("setPhoneState() setting same state %d", state);
+        return;
+    }
+
+    // if leaving call state, handle special case of active streams
+    // pertaining to sonification strategy see handleIncallSonification()
+    if (isInCall()) {
+        ALOGV("setPhoneState() in call state management: new state is %d", state);
+        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+            handleIncallSonification(stream, false, true);
+        }
+    }
+
+    // store previous phone state for management of sonification strategy below
+    int oldState = mPhoneState;
+    mPhoneState = state;
+    bool force = false;
+
+    // are we entering or starting a call
+    if (!isStateInCall(oldState) && isStateInCall(state)) {
+        ALOGV("  Entering call in setPhoneState()");
+        // force routing command to audio hardware when starting a call
+        // even if no device change is needed
+        force = true;
+    } else if (isStateInCall(oldState) && !isStateInCall(state)) {
+        ALOGV("  Exiting call in setPhoneState()");
+        // force routing command to audio hardware when exiting a call
+        // even if no device change is needed
+        force = true;
+    } else if (isStateInCall(state) && (state != oldState)) {
+        ALOGV("  Switching between telephony and VoIP in setPhoneState()");
+        // force routing command to audio hardware when switching between telephony and VoIP
+        // even if no device change is needed
+        force = true;
+    }
+
+    // check for device and output changes triggered by new phone state
+    newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
+    checkA2dpSuspend();
+    checkOutputForAllStrategies();
+    updateDevicesAndOutputs();
+
+    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
+
+    // force routing command to audio hardware when ending call
+    // even if no device change is needed
+    if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
+        newDevice = hwOutputDesc->device();
+    }
+
+    // when changing from ring tone to in call mode, mute the ringing tone
+    // immediately and delay the route change to avoid sending the ring tone
+    // tail into the earpiece or headset.
+    int delayMs = 0;
+    if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
+        // delay the device change command by twice the output latency to have some margin
+        // and be sure that audio buffers not yet affected by the mute are out when
+        // we actually apply the route change
+        delayMs = hwOutputDesc->mLatency*2;
+        setStreamMute(AudioSystem::RING, true, mPrimaryOutput);
+    }
+
+    if (isStateInCall(state)) {
+        for (size_t i = 0; i < mOutputs.size(); i++) {
+            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+            //take the biggest latency for all outputs
+            if (delayMs < desc->mLatency*2) {
+                delayMs = desc->mLatency*2;
+            }
+            //mute STRATEGY_MEDIA on all outputs
+            if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) {
+                setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
+                setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
+                    getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
+            }
+        }
+    }
+
+    // Ignore the delay to enable voice call on this target as the enabling the
+    // voice call has enough delay to make sure the ringtone audio completely
+    // played out
+    if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
+        delayMs = 0;
+    }
+
+    // change routing is necessary
+    setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
+
+    // if entering in call state, handle special case of active streams
+    // pertaining to sonification strategy see handleIncallSonification()
+    if (isStateInCall(state)) {
+        ALOGV("setPhoneState() in call state management: new state is %d", state);
+        // unmute the ringing tone after a sufficient delay if it was muted before
+        // setting output device above
+        if (oldState == AudioSystem::MODE_RINGTONE) {
+            setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS);
+        }
+        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+            handleIncallSonification(stream, true, true);
+        }
+    }
+
+    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
+    if (state == AudioSystem::MODE_RINGTONE &&
+        isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
+        mLimitRingtoneVolume = true;
+    } else {
+        mLimitRingtoneVolume = false;
+    }
+}
+
 }; // namespace androidi_audio_legacy
diff --git a/alsa_sound/AudioPolicyManagerALSA.h b/alsa_sound/AudioPolicyManagerALSA.h
index 2a7dfdb..91b7e13 100644
--- a/alsa_sound/AudioPolicyManagerALSA.h
+++ b/alsa_sound/AudioPolicyManagerALSA.h
@@ -35,6 +35,8 @@
                 AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
                 : AudioPolicyManagerBase(clientInterface) {}
 
+        virtual void setPhoneState(int state);
+
         virtual ~AudioPolicyManager() {}
 
 };
diff --git a/alsa_sound/audio_policy_hal.cpp b/alsa_sound/audio_policy_hal.cpp
index 1057a0f..bb50b34 100644
--- a/alsa_sound/audio_policy_hal.cpp
+++ b/alsa_sound/audio_policy_hal.cpp
@@ -68,7 +68,7 @@
 {
     struct qcom_audio_policy *qap = to_qap(pol);
     return qap->apm->setDeviceConnectionState(
-                    device,
+                    (AudioSystem::audio_devices)device,
                     (AudioSystem::device_connection_state)state,
                     device_address);
 }
@@ -80,14 +80,22 @@
 {
     const struct qcom_audio_policy *qap = to_cqap(pol);
     return (audio_policy_dev_state_t)qap->apm->getDeviceConnectionState(
-                    device,
+                    (AudioSystem::audio_devices)device,
                     device_address);
 }
 
 static void ap_set_phone_state(struct audio_policy *pol, audio_mode_t state)
 {
     struct qcom_audio_policy *qap = to_qap(pol);
-    qap->apm->setPhoneState(state);
+    // as this is the legacy API, don't change it to use audio_mode_t instead of int
+    qap->apm->setPhoneState((int) state);
+}
+
+    /* indicate a change in ringer mode */
+static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode,
+                               uint32_t mask)
+{
+    // deprecated, never called
 }
 
     /* force using a specific device category for the specified usage */
@@ -125,58 +133,18 @@
     return qap->apm->initCheck();
 }
 
-#ifdef QCOM_TUNNEL_LPA_ENABLED
-static audio_io_handle_t ap_get_session(struct audio_policy *pol,
-                                       audio_stream_type_t stream,
-                                       audio_format_t format,
-                                       audio_policy_output_flags_t flags,
-                                       int sessionId,
-                                       uint32_t samplingRate,
-                                       uint32_t channels)
-{
-    struct qcom_audio_policy *qap = to_qap(pol);
-
-    ALOGV("%s: tid %d", __func__, gettid());
-    return qap->apm->getSession((AudioSystem::stream_type)stream,
-                               format, (AudioSystem::output_flags)flags,
-                               sessionId,
-                               samplingRate,
-                               channels);
-}
-
-static void ap_pause_session(struct audio_policy *pol, audio_io_handle_t output,
-                          audio_stream_type_t stream)
-{
-    struct qcom_audio_policy *qap = to_qap(pol);
-    qap->apm->pauseSession(output, (AudioSystem::stream_type)stream);
-}
-
-static void ap_resume_session(struct audio_policy *pol, audio_io_handle_t output,
-                          audio_stream_type_t stream)
-{
-    struct qcom_audio_policy *qap = to_qap(pol);
-    qap->apm->resumeSession(output, (AudioSystem::stream_type)stream);
-}
-
-static void ap_release_session(struct audio_policy *pol, audio_io_handle_t output)
-{
-    struct qcom_audio_policy *qap = to_qap(pol);
-    qap->apm->releaseSession(output);
-}
-#endif
-
 static audio_io_handle_t ap_get_output(struct audio_policy *pol,
                                        audio_stream_type_t stream,
                                        uint32_t sampling_rate,
                                        audio_format_t format,
-                                       uint32_t channels,
+                                       audio_channel_mask_t channelMask,
                                        audio_output_flags_t flags)
 {
     struct qcom_audio_policy *qap = to_qap(pol);
 
     ALOGV("%s: tid %d", __func__, gettid());
     return qap->apm->getOutput((AudioSystem::stream_type)stream,
-                               sampling_rate, format, channels,
+                               sampling_rate, (int) format, channelMask,
                                (AudioSystem::output_flags)flags);
 }
 
@@ -206,11 +174,11 @@
 static audio_io_handle_t ap_get_input(struct audio_policy *pol, audio_source_t inputSource,
                                       uint32_t sampling_rate,
                                       audio_format_t format,
-                                      uint32_t channels,
+                                      audio_channel_mask_t channelMask,
                                       audio_in_acoustics_t acoustics)
 {
     struct qcom_audio_policy *qap = to_qap(pol);
-    return qap->apm->getInput(inputSource, sampling_rate, format, channels,
+    return qap->apm->getInput((int) inputSource, sampling_rate, (int) format, channelMask,
                               (AudioSystem::audio_in_acoustics)acoustics);
 }
 
@@ -248,7 +216,7 @@
     struct qcom_audio_policy *qap = to_qap(pol);
     return qap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,
                                           index,
-                                          AUDIO_DEVICE_OUT_DEFAULT); 
+                                          AUDIO_DEVICE_OUT_DEFAULT);
 }
 
 static int ap_get_stream_volume_index(const struct audio_policy *pol,
@@ -261,13 +229,6 @@
                                           AUDIO_DEVICE_OUT_DEFAULT);
 }
 
-static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol,
-                                           audio_stream_type_t stream)
-{
-    const struct qcom_audio_policy *qap = to_cqap(pol);
-    return qap->apm->getStrategyForStream((AudioSystem::stream_type)stream);
-}
-
 static int ap_set_stream_volume_index_for_device(struct audio_policy *pol,
                                       audio_stream_type_t stream,
                                       int index,
@@ -287,7 +248,14 @@
    const struct qcom_audio_policy *qap = to_cqap(pol);
    return qap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream,
                                           index,
-                                          AUDIO_DEVICE_OUT_DEFAULT);
+                                          device);
+}
+
+static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol,
+                                           audio_stream_type_t stream)
+{
+    const struct qcom_audio_policy *qap = to_cqap(pol);
+    return qap->apm->getStrategyForStream((AudioSystem::stream_type)stream);
 }
 
 static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol,
@@ -298,14 +266,14 @@
 }
 
 static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol,
-                                            struct effect_descriptor_s *desc)
+                                            const struct effect_descriptor_s *desc)
 {
     struct qcom_audio_policy *qap = to_qap(pol);
     return qap->apm->getOutputForEffect(desc);
 }
 
 static int ap_register_effect(struct audio_policy *pol,
-                              struct effect_descriptor_s *desc,
+                              const struct effect_descriptor_s *desc,
                               audio_io_handle_t io,
                               uint32_t strategy,
                               int session,
@@ -332,7 +300,13 @@
                                 uint32_t in_past_ms)
 {
     const struct qcom_audio_policy *qap = to_cqap(pol);
-    return qap->apm->isStreamActive(stream, in_past_ms);
+    return qap->apm->isStreamActive((int) stream, in_past_ms);
+}
+
+static bool ap_is_source_active(const struct audio_policy *pol, audio_source_t source)
+{
+    const struct qcom_audio_policy *qap = to_cqap(pol);
+    return qap->apm->isSourceActive(source);
 }
 
 static int ap_dump(const struct audio_policy *pol, int fd)
@@ -359,18 +333,13 @@
     qap->policy.set_device_connection_state = ap_set_device_connection_state;
     qap->policy.get_device_connection_state = ap_get_device_connection_state;
     qap->policy.set_phone_state = ap_set_phone_state;
+    qap->policy.set_ringer_mode = ap_set_ringer_mode;
     qap->policy.set_force_use = ap_set_force_use;
     qap->policy.get_force_use = ap_get_force_use;
     qap->policy.set_can_mute_enforced_audible =
         ap_set_can_mute_enforced_audible;
     qap->policy.init_check = ap_init_check;
     qap->policy.get_output = ap_get_output;
-#ifdef QCOM_TUNNEL_LPA_ENABLED
-    qap->policy.get_session = ap_get_session;
-    qap->policy.pause_session = ap_pause_session;
-    qap->policy.resume_session = ap_resume_session;
-    qap->policy.release_session = ap_release_session;
-#endif
     qap->policy.start_output = ap_start_output;
     qap->policy.stop_output = ap_stop_output;
     qap->policy.release_output = ap_release_output;
@@ -390,6 +359,7 @@
     qap->policy.unregister_effect = ap_unregister_effect;
     qap->policy.set_effect_enabled = ap_set_effect_enabled;
     qap->policy.is_stream_active = ap_is_stream_active;
+    qap->policy.is_source_active = ap_is_source_active;
     qap->policy.dump = ap_dump;
 
     qap->service = service;