Promotion of av-userspace.lnx.1.0-00032.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
Ib08ec8c6aef6d88bf4e4d413fb5d95e4167cce30 hal: close audio calibration fd
948361 I7fd8b7340e6c78ee6d00b41ccf679582338c011a policy: Avoid unnecessary set_parameter calls
959131 If18e352971e92e82f4b67178924675a4a39c8460 hal: Fix closure of hardware dependent node
Ifa0b214d16527973277a5c84b8a4f3fbd0760d07 policy_hal: fix for volume burst during FM device switch
948361 Id614d32df7f35ac93dd029a08b10e19f64ac631e policy: Delay FM volume update to start of FM playback
959009 If66cc1e3d5467bf7d03137fdbbffd724a57ecaf6 hal: Validate active input before accessing source
CRs-Fixed: 948361, 959009, 959131
Conflicts:
hal/msm8916/platform.c
hal/msm8974/platform.c
Change-Id: I2334c946c86313f3886ee71ce15d3dacdf9464c9
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index c46f419..8c729ff 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -1000,7 +1000,8 @@
out_snd_device = SND_DEVICE_NONE;
if (in_snd_device == SND_DEVICE_NONE) {
audio_devices_t out_device = AUDIO_DEVICE_NONE;
- if ((adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+ if (adev->active_input &&
+ (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
(adev->mode == AUDIO_MODE_IN_COMMUNICATION &&
adev->active_input->source == AUDIO_SOURCE_MIC)) &&
adev->primary_output && !adev->primary_output->standby) {
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index a513048..f630270 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -247,6 +247,7 @@
codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
char ec_ref_mixer_path[64];
char codec_version[CODEC_VERSION_MAX_LENGTH];
+ int hw_dep_fd;
};
static bool is_external_codec = false;
@@ -1386,14 +1387,15 @@
return ret;
}
-static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
+static void send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
struct platform_data *plat_data, int fd)
{
- int ret = 0, type;
+ int type;
for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
struct wcdcal_ioctl_buffer codec_buffer;
struct param_data calib;
+ int ret;
/* MAD calibration is handled by sound trigger HAL, skip here */
if (type == WCD9XXX_MAD_CAL)
@@ -1410,14 +1412,14 @@
&calib);
if (ret < 0) {
ALOGE("%s get_calibration failed\n", __func__);
- return ret;
+ continue;
}
calib.get_size = 0;
calib.buff = malloc(calib.buff_size);
if(calib.buff == NULL) {
ALOGE("%s mem allocation for %d bytes for %s failed\n"
, __func__, calib.buff_size, cal_name_info[type]);
- return -1;
+ continue;
}
ret = acdb_loader_get_calibration(cal_name_info[type],
sizeof(struct param_data), &calib);
@@ -1425,7 +1427,7 @@
ALOGE("%s get_calibration failed type=%s calib.size=%d\n"
, __func__, cal_name_info[type], codec_buffer.size);
free(calib.buff);
- return ret;
+ continue;
}
codec_buffer.buffer = calib.buff;
codec_buffer.size = calib.data_size;
@@ -1437,14 +1439,14 @@
, __func__, cal_name_info[type], codec_buffer.size);
free(calib.buff);
}
- return ret;
}
static void audio_hwdep_send_cal(struct platform_data *plat_data)
{
- int fd;
+ int fd = plat_data->hw_dep_fd;
- fd = hw_util_open(plat_data->adev->snd_card);
+ if (fd < 0)
+ fd = hw_util_open(plat_data->adev->snd_card);
if (fd == -1) {
ALOGE("%s error open\n", __func__);
return;
@@ -1456,11 +1458,15 @@
if (acdb_loader_get_calibration == NULL) {
ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
dlerror());
+ if (fd >= 0) {
+ close(fd);
+ plat_data->hw_dep_fd = -1;
+ }
return;
}
- if (send_codec_cal(acdb_loader_get_calibration, plat_data, fd) < 0)
- ALOGE("%s: Could not send anc cal", __FUNCTION__);
- close(fd);
+
+ send_codec_cal(acdb_loader_get_calibration, plat_data, fd);
+ plat_data->hw_dep_fd = fd;
}
const char * get_snd_card_name_for_acdb_loader(const char *snd_card_name) {
@@ -1683,6 +1689,7 @@
my_data->hd_voice = false;
my_data->edid_info = NULL;
my_data->is_wsa_speaker = false;
+ my_data->hw_dep_fd = -1;
property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
@@ -1907,6 +1914,11 @@
my_data->edid_info = NULL;
}
+ if (my_data->hw_dep_fd >= 0) {
+ close(my_data->hw_dep_fd);
+ my_data->hw_dep_fd = -1;
+ }
+
hw_info_deinit(my_data->hw_info);
close_csd_client(my_data->csd);
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index f243790..179593d 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -243,6 +243,7 @@
char ec_ref_mixer_path[64];
codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
char codec_version[CODEC_VERSION_MAX_LENGTH];
+ int hw_dep_fd;
};
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -1212,9 +1213,10 @@
static void audio_hwdep_send_cal(struct platform_data *plat_data)
{
- int fd;
+ int fd = plat_data->hw_dep_fd;
- fd = hw_util_open(plat_data->adev->snd_card);
+ if (fd < 0)
+ fd = hw_util_open(plat_data->adev->snd_card);
if (fd == -1) {
ALOGE("%s error open\n", __func__);
return;
@@ -1226,11 +1228,15 @@
if (acdb_loader_get_calibration == NULL) {
ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
dlerror());
+ if (fd >= 0) {
+ close(fd);
+ plat_data->hw_dep_fd = -1;
+ }
return;
}
send_codec_cal(acdb_loader_get_calibration, plat_data, fd);
- close(fd);
+ plat_data->hw_dep_fd = fd;
}
static int platform_acdb_init(void *platform)
@@ -1405,6 +1411,7 @@
my_data->slowtalk = false;
my_data->hd_voice = false;
my_data->edid_info = NULL;
+ my_data->hw_dep_fd = -1;
property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
@@ -1621,6 +1628,11 @@
my_data->edid_info = NULL;
}
+ if (my_data->hw_dep_fd >= 0) {
+ close(my_data->hw_dep_fd);
+ my_data->hw_dep_fd = -1;
+ }
+
hw_info_deinit(my_data->hw_info);
close_csd_client(my_data->csd);
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 8577620..1b1578e 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -279,15 +279,20 @@
#ifdef FM_POWER_OPT
// handle FM device connection state to trigger FM AFE loopback
- if(device == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
+ 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;
+ mFMIsActive = true;
} else {
+ mFMIsActive = false;
mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, -1);
}
AudioParameter param = AudioParameter();
+ float volumeDb = mPrimaryOutput->mCurVolume[AUDIO_STREAM_MUSIC];
+ mPrevFMVolumeDb = volumeDb;
+ param.addFloat(String8("fm_volume"), Volume::DbToAmpl(volumeDb));
param.addInt(String8("handle_fm"), (int)newDevice);
mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString());
}
@@ -1270,10 +1275,16 @@
}
#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);
+ outputDesc == mPrimaryOutput && mFMIsActive) {
+ /* Avoid unnecessary set_parameter calls as it puts the primary
+ outputs FastMixer in HOT_IDLE leading to breaks in audio */
+ if (volumeDb != mPrevFMVolumeDb) {
+ mPrevFMVolumeDb = volumeDb;
+ AudioParameter param = AudioParameter();
+ param.addFloat(String8("fm_volume"), Volume::DbToAmpl(volumeDb));
+ //Double delayMs to avoid sound burst while device switch.
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString(), delayMs*2);
+ }
#endif /* FM_POWER_OPT end */
}
@@ -2037,7 +2048,9 @@
: AudioPolicyManager(clientInterface),
mHdmiAudioDisabled(false),
mHdmiAudioEvent(false),
- mPrevPhoneState(0)
+ mPrevPhoneState(0),
+ mPrevFMVolumeDb(0.0f),
+ mFMIsActive(false)
{
char ssr_enabled[PROPERTY_VALUE_MAX] = {0};
bool prop_ssr_enabled = false;
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 55d59ac..af8c2a8 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -154,6 +154,8 @@
// Used for record + playback concurrency
bool mIsInputRequestOnProgress;
#endif
+ float mPrevFMVolumeDb;
+ bool mFMIsActive;
};
};