Merge "hal: spk_protection: fix crash due to invalid param sent"
diff --git a/hal/Android.mk b/hal/Android.mk
index 99b6b39..efdde67 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -199,6 +199,10 @@
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 688e265..c46c225 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -77,6 +77,8 @@
/* 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)
@@ -530,6 +532,103 @@
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)
{
@@ -547,6 +646,7 @@
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);
}
void audio_extn_get_parameters(const struct audio_device *adev,
@@ -560,6 +660,7 @@
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);
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 138bd3c..4f69bd5 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2246,9 +2246,13 @@
{
struct stream_out *out = (struct stream_out *)stream;
struct audio_device *adev = out->dev;
- if (is_offload_usecase(out->usecase) && (dsp_frames != NULL)) {
+
+ if (dsp_frames == NULL)
+ return -EINVAL;
+
+ *dsp_frames = 0;
+ if (is_offload_usecase(out->usecase)) {
ssize_t ret = 0;
- *dsp_frames = 0;
pthread_mutex_lock(&out->lock);
if (out->compr != NULL) {
ret = compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
@@ -2276,6 +2280,9 @@
} else {
return 0;
}
+ } else if (audio_is_linear_pcm(out->format)) {
+ *dsp_frames = out->written;
+ return 0;
} else
return -EINVAL;
}
@@ -2807,6 +2814,9 @@
return -ENOMEM;
}
+ pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
+
if (devices == AUDIO_DEVICE_NONE)
devices = AUDIO_DEVICE_OUT_SPEAKER;
@@ -3078,9 +3088,6 @@
/* out->muted = false; by calloc() */
/* out->written = 0; by calloc() */
- pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
- pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
-
config->format = out->stream.common.get_format(&out->stream.common);
config->channel_mask = out->stream.common.get_channels(&out->stream.common);
config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index e061fdc..e9780bc 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -86,7 +86,8 @@
#define MIN_COMPRESS_PASSTHROUGH_FRAGMENT_SIZE (2 * 1024)
#define MAX_COMPRESS_PASSTHROUGH_FRAGMENT_SIZE (8 * 1024)
-#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
+#define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y))
+#define ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y)))
/*
* This file will have a maximum of 38 bytes:
*
@@ -3273,12 +3274,15 @@
* info->sample_rate
* (bits_per_sample >> 3)
* popcount(info->channel_mask))/1000;
- // align with LCM of 2, 4, 6, 8
- fragment_size = ALIGN( fragment_size, 24 );
if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
+ // To have same PCM samples for all channels, the buffer size requires to
+ // be multiple of (number of channels * bytes per sample)
+ // For writes to succeed, the buffer must be written at address which is multiple of 32
+ // Alignment of 96 satsfies both of the above requirements
+ fragment_size = ALIGN(fragment_size, 96);
ALOGI("PCM offload Fragment size to %d bytes", fragment_size);
return fragment_size;
@@ -3290,8 +3294,15 @@
ALOGV("%s bit width: %d, sample rate: %d", __func__, bit_width, sample_rate);
int ret = 0;
+ const char *snd_card_name = mixer_get_name(adev->mixer);
if (bit_width != adev->cur_codec_backend_bit_width) {
- const char * mixer_ctl_name = "SLIM_0_RX Format";
+ const char * mixer_ctl_name;
+ if (!strncmp(snd_card_name, "msm8952-tomtom-snd-card",
+ sizeof("msm8952-tomtom-snd-card"))) {
+ mixer_ctl_name = "SLIM_0_RX Format";
+ }
+ else
+ mixer_ctl_name = "MI2S_RX Format";
struct mixer_ctl *ctl;
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
if (!ctl) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 8debc0a..24e23e6 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -380,13 +380,13 @@
[SND_DEVICE_NONE] = -1,
[SND_DEVICE_OUT_HANDSET] = 7,
[SND_DEVICE_OUT_SPEAKER] = 14,
- [SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = 14,
- [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 14,
+ [SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = 130,
+ [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 130,
[SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
[SND_DEVICE_OUT_HEADPHONES] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
- [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 10,
- [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 10,
+ [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 130,
+ [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 130,
[SND_DEVICE_OUT_VOICE_HANDSET] = 7,
[SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
[SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index ec48a71..76128e5 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1605,11 +1605,13 @@
}
} else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
ALOGD("copl: Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
- //duration checks only valid for MP3/AAC formats,
+ //duration checks only valid for MP3/AAC/WMA formats,
//do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats
if ((offloadInfo.format == AUDIO_FORMAT_MP3) ||
((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
+ ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA) ||
+ ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA_PRO) ||
pcmOffload)
return false;
}