mm-audio: Fix delay at the start of MT voice call
- Reducing the delay for playing the RINGTONE
before voice call is accepted saves,appr 340ms.
- on this platform reducing the delay wont affect
the RINGTONE as the delay in setting up voice
path after accepting the voice call will
compensate RINGTONE buffers with kernel and
firmware played on the device.
Bug-id: 7612431
Change-Id: Iff5b4545ca7e2316178b0db8cb6760b173c189be
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;