Merge "hal: Add performance lock during device switch"
diff --git a/hal/Android.mk b/hal/Android.mk
index e457b83..0e0f8b3 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -85,8 +85,8 @@
LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
endif
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM)),true)
- LOCAL_CFLAGS += -DFM_ENABLED
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM_POWER_OPT)),true)
+ LOCAL_CFLAGS += -DFM_POWER_OPT
LOCAL_SRC_FILES += audio_extn/fm.c
endif
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index ce8f965..fe959be 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -82,7 +82,7 @@
#define AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE "offload_num_active"
#define AUDIO_PARAMETER_HPX "HPX"
-#ifndef FM_ENABLED
+#ifndef FM_POWER_OPT
#define audio_extn_fm_set_parameters(adev, parms) (0)
#else
void audio_extn_fm_set_parameters(struct audio_device *adev,
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index b4848a4..ccdff09 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -59,13 +59,8 @@
#define AUDIO_OUTPUT_FLAG_INCALL_MUSIC 0x8000
#endif
-#ifndef FM_ENABLED
-#define AUDIO_DEVICE_OUT_FM 0x80000
-#define AUDIO_DEVICE_OUT_FM_TX 0x100000
-#define AUDIO_SOURCE_FM_RX 9
-#define AUDIO_SOURCE_FM_RX_A2DP 10
-#define AUDIO_DEVICE_IN_FM_RX (AUDIO_DEVICE_BIT_IN | 0x8000)
-#define AUDIO_DEVICE_IN_FM_RX_A2DP (AUDIO_DEVICE_BIT_IN | 0x10000)
+#ifndef AUDIO_DEVICE_OUT_FM_TX
+#define AUDIO_DEVICE_OUT_FM_TX 0x8000000
#endif
#ifndef FLAC_OFFLOAD_ENABLED
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index ed3776c..6381e68 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -31,10 +31,11 @@
#include <stdlib.h>
#include <cutils/str_parms.h>
-#ifdef FM_ENABLED
+#ifdef FM_POWER_OPT
#define AUDIO_PARAMETER_KEY_HANDLE_FM "handle_fm"
#define AUDIO_PARAMETER_KEY_FM_VOLUME "fm_volume"
#define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
+#define FM_LOOPBACK_DRAIN_TIME_MS 2
static struct pcm_config pcm_config_fm = {
.channels = 2,
@@ -65,7 +66,7 @@
.scard_state = SND_CARD_STATE_ONLINE,
};
-static int32_t fm_set_volume(struct audio_device *adev, float value)
+static int32_t fm_set_volume(struct audio_device *adev, float value, bool persist)
{
int32_t vol, ret = 0;
struct mixer_ctl *ctl;
@@ -82,7 +83,8 @@
value = 1.0;
}
vol = lrint((value * 0x2000) + 0.5);
- fmmod.fm_volume = value;
+ if (persist)
+ fmmod.fm_volume = value;
if (!fmmod.is_fm_running) {
ALOGV("%s: FM not active, ignoring set_fm_volume call", __func__);
@@ -202,7 +204,7 @@
pcm_start(fmmod.fm_pcm_tx);
fmmod.is_fm_running = true;
- fm_set_volume(adev, fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -263,8 +265,11 @@
adev->primary_output->devices = val & ~AUDIO_DEVICE_OUT_FM;
fm_start(adev);
} else if (!(val & AUDIO_DEVICE_OUT_FM)
- && fmmod.is_fm_running == true)
+ && fmmod.is_fm_running == true) {
+ fm_set_volume(adev, 0, false);
+ usleep(FM_LOOPBACK_DRAIN_TIME_MS*1000);
fm_stop(adev);
+ }
}
}
@@ -278,7 +283,7 @@
goto exit;
}
ALOGD("%s: set_fm_volume usecase", __func__);
- fm_set_volume(adev, vol);
+ fm_set_volume(adev, vol, true);
}
#ifdef RECORD_PLAY_CONCURRENCY
@@ -293,10 +298,10 @@
ALOGD("Record play concurrency OFF Forcing FM device reroute");
select_devices(adev, USECASE_AUDIO_PLAYBACK_FM);
- fm_set_volume(adev,fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
}
#endif
exit:
ALOGV("%s: exit", __func__);
}
-#endif /* FM_ENABLED end */
+#endif /* FM_POWER_OPT end */
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index 69c9341..6990f23 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -240,6 +240,18 @@
hw_info->snd_devices = NULL;
hw_info->num_snd_devices = 0;
strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8952-sku1-snd-card")) {
+ strlcpy(hw_info->type, "", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
+ hw_info->snd_devices = NULL;
+ hw_info->num_snd_devices = 0;
+ strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8952-sku2-snd-card")) {
+ strlcpy(hw_info->type, "", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
+ hw_info->snd_devices = NULL;
+ hw_info->num_snd_devices = 0;
+ strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
} else {
ALOGW("%s: Not an 8x16/8939/8909/8952 device", __func__);
}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index a478f93..44ee73a 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -51,6 +51,8 @@
#define MIXER_XML_PATH_SKUE "/system/etc/mixer_paths_skue.xml"
#define MIXER_XML_PATH_SKUL "/system/etc/mixer_paths_skul.xml"
#define MIXER_XML_PATH_SKUM "/system/etc/mixer_paths_qrd_skum.xml"
+#define MIXER_XML_PATH_SKU1 "/system/etc/mixer_paths_qrd_sku1.xml"
+#define MIXER_XML_PATH_SKU2 "/system/etc/mixer_paths_qrd_sku2.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml"
@@ -902,6 +904,20 @@
msm_device_to_be_id = msm_device_to_be_id_external_codec;
msm_be_id_array_len =
sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
+ } else if (!strncmp(snd_card_name, "msm8952-sku1-snd-card",
+ sizeof("msm8952-sku1-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_SKU1,
+ sizeof(MIXER_XML_PATH_SKU1));
+ msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+ } else if (!strncmp(snd_card_name, "msm8952-sku2-snd-card",
+ sizeof("msm8952-sku2-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_SKU2,
+ sizeof(MIXER_XML_PATH_SKU2));
+ msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
} else if (!strncmp(snd_card_name, "msm8952-skum-snd-card",
sizeof("msm8952-skum-snd-card"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUM,
@@ -2792,9 +2808,7 @@
}
}
}
- } else if (source == AUDIO_SOURCE_FM_RX ||
- source == AUDIO_SOURCE_FM_RX_A2DP ||
- source == AUDIO_SOURCE_FM_TUNER) {
+ } else if (source == AUDIO_SOURCE_FM_TUNER) {
snd_device = SND_DEVICE_IN_CAPTURE_FM;
} else if (source == AUDIO_SOURCE_DEFAULT) {
goto exit;
@@ -2837,8 +2851,7 @@
} else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_FM_RX ||
- in_device & AUDIO_DEVICE_IN_FM_TUNER) {
+ } else if (in_device & AUDIO_DEVICE_IN_FM_TUNER) {
snd_device = SND_DEVICE_IN_CAPTURE_FM;
} else {
ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
@@ -3522,8 +3535,7 @@
int platform_update_usecase_from_source(int source, int usecase)
{
ALOGV("%s: input source :%d", __func__, source);
- if (source == AUDIO_SOURCE_FM_RX_A2DP ||
- source == AUDIO_SOURCE_FM_TUNER)
+ if (source == AUDIO_SOURCE_FM_TUNER)
usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
return usecase;
}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index cc48b9e..0af5a08 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -2657,9 +2657,7 @@
}
}
}
- } else if (source == AUDIO_SOURCE_FM_RX ||
- source == AUDIO_SOURCE_FM_RX_A2DP||
- source == AUDIO_SOURCE_FM_TUNER) {
+ } else if (source == AUDIO_SOURCE_FM_TUNER) {
snd_device = SND_DEVICE_IN_CAPTURE_FM;
} else if (source == AUDIO_SOURCE_DEFAULT) {
goto exit;
@@ -2702,8 +2700,7 @@
} else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_FM_RX ||
- in_device & AUDIO_DEVICE_IN_FM_TUNER) {
+ } else if (in_device & AUDIO_DEVICE_IN_FM_TUNER) {
snd_device = SND_DEVICE_IN_CAPTURE_FM;
} else {
ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
@@ -3452,8 +3449,7 @@
int platform_update_usecase_from_source(int source, int usecase)
{
ALOGV("%s: input source :%d", __func__, source);
- if (source == AUDIO_SOURCE_FM_RX_A2DP ||
- source == AUDIO_SOURCE_FM_TUNER)
+ if (source == AUDIO_SOURCE_FM_TUNER)
usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
return usecase;
}
diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index 52ed11d..70814d8 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -59,6 +59,10 @@
LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM_POWER_OPT)),true)
+LOCAL_CFLAGS += -DFM_POWER_OPT
+endif
+
LOCAL_MODULE := libaudiopolicymanager
include $(BUILD_SHARED_LIBRARY)
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 46c58c5..7876e5b 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -26,7 +26,6 @@
#else
#define ALOGVV(a...) do { } while(0)
#endif
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
// A device mask for all audio output devices that are considered "remote" when evaluating
// active output devices in isStreamActiveRemotely()
@@ -35,9 +34,6 @@
// type alone is not enough: the address must match too
#define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \
AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
-// Following delay should be used if the calculated routing delay from all active
-// input streams is higher than this value
-#define MAX_VOICE_CALL_START_DELAY_MS 100
#include <inttypes.h>
#include <math.h>
@@ -254,6 +250,23 @@
audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevice);
}
+
+#ifdef FM_POWER_OPT
+ // handle FM device connection state to trigger FM AFE loopback
+ if(device == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
+ audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+ if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+ mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, 1);
+ newDevice = newDevice | AUDIO_DEVICE_OUT_FM;
+ } else {
+ mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, -1);
+ }
+ AudioParameter param = AudioParameter();
+ param.addInt(String8("handle_fm"), (int)newDevice);
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString());
+ }
+#endif /* FM_POWER_OPT end */
+
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
@@ -397,6 +410,13 @@
return false;
}
+ // Check if offload has been disabled
+ bool offloadDisabled = property_get_bool("audio.offload.disable", false);
+ if (offloadDisabled) {
+ ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+ return false;
+ }
+
char propValue[PROPERTY_VALUE_MAX];
bool pcmOffload = false;
#ifdef PCM_OFFLOAD_ENABLED
@@ -426,13 +446,13 @@
}
#endif
if (!pcmOffload) {
- // Check if offload has been disabled
- if (property_get("audio.offload.disable", propValue, "0")) {
- if (atoi(propValue) != 0) {
- ALOGV("offload disabled by audio.offload.disable=%s", propValue );
- return false;
- }
+
+ bool compressedOffloadDisabled = property_get_bool("audio.offload.compress.disable", false);
+ if (compressedOffloadDisabled) {
+ ALOGI("compressed offload disabled by audio.offload.compress.disable=%d", compressedOffloadDisabled);
+ return false;
}
+
//check if it's multi-channel AAC (includes sub formats) and FLAC format
if ((popcount(offloadInfo.channel_mask) > 2) &&
(((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
@@ -853,9 +873,6 @@
setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
}
- ALOGV("Setting the delay from %dms to %dms", delayMs,
- MIN(delayMs, MAX_VOICE_CALL_START_DELAY_MS));
- delayMs = MIN(delayMs, MAX_VOICE_CALL_START_DELAY_MS);
}
if (hasPrimaryOutput()) {
@@ -1235,6 +1252,13 @@
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
mLastVoiceVolume = voiceVolume;
}
+#ifdef FM_POWER_OPT
+ } else if (stream == AUDIO_STREAM_MUSIC && hasPrimaryOutput() &&
+ outputDesc == mPrimaryOutput) {
+ AudioParameter param = AudioParameter();
+ param.addFloat(String8("fm_volume"), Volume::DbToAmpl(volumeDb));
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString(), delayMs);
+#endif /* FM_POWER_OPT end */
}
return NO_ERROR;
@@ -1264,7 +1288,17 @@
{
audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
- bool pcmOffloadEnabled = property_get_bool("audio.offload.track.enable", false);
+ bool offloadDisabled = property_get_bool("audio.offload.disable", false);
+ bool pcmOffloadEnabled = false;
+
+ if (offloadDisabled) {
+ ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+ }
+
+ //read track offload property only if the global offload switch is off.
+ if (!offloadDisabled) {
+ pcmOffloadEnabled = property_get_bool("audio.offload.track.enable", false);
+ }
if (offloadInfo == NULL && pcmOffloadEnabled) {
tOffloadInfo.sample_rate = samplingRate;
@@ -1276,7 +1310,7 @@
ALOGV("found attribute .. setting usage %d ", attr->usage);
tOffloadInfo.usage = attr->usage;
} else {
- ALOGD("%s:: attribute is NULL .. no usage set", __func__);
+ ALOGI("%s:: attribute is NULL .. no usage set", __func__);
}
offloadInfo = &tOffloadInfo;
}