Merge "policy_hal: Add Direct PCM flags for track offload"
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 858a00e..040b140 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -77,6 +77,7 @@
#define WAIT_TIME_SPKR_CALIB (60 * 1000 * 1000)
#define MIN_SPKR_IDLE_SEC (60 * 30)
+#define WAKEUP_MIN_IDLE_CHECK 30
/*Once calibration is started sleep for 1 sec to allow
the calibration to kick off*/
@@ -554,7 +555,7 @@
}
break;
} else if (status.status == -EAGAIN) {
- ALOGD("%s: spkr_prot_thread try again", __func__);
+ ALOGV("%s: spkr_prot_thread try again", __func__);
usleep(WAIT_FOR_GET_CALIB_STATUS);
} else {
ALOGE("%s: spkr_prot_thread get failed status %d",
@@ -734,18 +735,22 @@
if (is_speaker_in_use(&sec)) {
ALOGV("%s: WSA Speaker in use retry calibration", __func__);
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
} else {
+ ALOGD("%s: wsa speaker idle %ld,minimum time %ld", __func__, sec, min_idle_time);
if (sec < min_idle_time) {
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
}
- ALOGV("%s: wsa speaker idle %ld min time %ld", __func__, sec, min_idle_time);
goahead = true;
}
if (!list_empty(&adev->usecase_list)) {
ALOGD("%s: Usecase active re-try calibration", __func__);
- goahead = false;
+ pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
+ continue;
}
if (goahead) {
if (spk_1_tzn > 0) {
@@ -777,15 +782,17 @@
if (t0_spk_1 < TZ_TEMP_MIN_THRESHOLD ||
t0_spk_1 > TZ_TEMP_MAX_THRESHOLD) {
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
}
+ ALOGD("%s: temp T0 for spkr1 %d\n", __func__, t0_spk_1);
/*Convert temp into q6 format*/
t0_spk_1 = (t0_spk_1 * (1 << 6));
- ALOGD("%s: temp T0 for spkr1 %d\n", __func__, t0_spk_1);
} else {
ALOGV("%s: thermal equilibrium failed for spkr1 in %d/%d readings\n",
__func__, i, NUM_ATTEMPTS);
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
}
}
@@ -817,15 +824,17 @@
if (t0_spk_2 < TZ_TEMP_MIN_THRESHOLD ||
t0_spk_2 > TZ_TEMP_MAX_THRESHOLD) {
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
}
+ ALOGD("%s: temp T0 for spkr2 %d\n", __func__, t0_spk_2);
/*Convert temp into q6 format*/
t0_spk_2 = (t0_spk_2 * (1 << 6));
- ALOGD("%s: temp T0 for spkr2 %d\n", __func__, t0_spk_2);
} else {
ALOGV("%s: thermal equilibrium failed for spkr2 in %d/%d readings\n",
__func__, i, NUM_ATTEMPTS);
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
}
}
@@ -859,19 +868,22 @@
if (is_speaker_in_use(&sec)) {
ALOGV("%s: Speaker in use retry calibration", __func__);
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
} else {
if (sec < min_idle_time) {
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
continue;
}
- ALOGD("%s: speaker idle %ld min time %ld", __func__, sec, min_idle_time);
goahead = true;
}
if (!list_empty(&adev->usecase_list)) {
ALOGD("%s: Usecase active re-try calibration", __func__);
goahead = false;
pthread_mutex_unlock(&adev->lock);
+ sleep(WAKEUP_MIN_IDLE_CHECK);
+ continue;
}
if (goahead) {
int status;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 8e974a9..308a6a8 100755
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -434,7 +434,7 @@
audio_extn_utils_send_audio_calibration(adev, usecase);
strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
platform_add_backend_name(mixer_path, snd_device, usecase);
- ALOGV("%s: apply mixer and update path: %s", __func__, mixer_path);
+ ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
audio_route_apply_and_update_path(adev->audio_route, mixer_path);
ALOGV("%s: exit", __func__);
return 0;
@@ -456,7 +456,7 @@
snd_device = usecase->out_snd_device;
strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
platform_add_backend_name(mixer_path, snd_device, usecase);
- ALOGV("%s: reset and update mixer path: %s", __func__, mixer_path);
+ ALOGD("%s: reset and update mixer path: %s", __func__, mixer_path);
audio_route_reset_and_update_path(adev->audio_route, mixer_path);
audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_FREE);
audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_FREE);
@@ -513,8 +513,7 @@
return -EINVAL;
}
} else {
- ALOGV("%s: snd_device(%d: %s)", __func__,
- snd_device, device_name);
+ ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
/* due to the possibility of calibration overwrite between listen
and audio, notify listen hal before audio calibration is sent */
audio_extn_sound_trigger_update_device_status(snd_device,
@@ -558,8 +557,7 @@
}
if (adev->snd_dev_ref_cnt[snd_device] == 0) {
- ALOGV("%s: snd_device(%d: %s)", __func__,
- snd_device, device_name);
+ ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
/* exit usb play back thread */
if(SND_DEVICE_OUT_USB_HEADSET == snd_device ||
SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET == snd_device)
@@ -1143,11 +1141,19 @@
}
break;
}
+
+ ALOGV("%s: pcm_prepare", __func__);
+ ret = pcm_prepare(in->pcm);
+ if (ret < 0) {
+ ALOGE("%s: pcm_prepare returned %d", __func__, ret);
+ pcm_close(in->pcm);
+ in->pcm = NULL;
+ goto error_open;
+ }
+
audio_extn_perf_lock_release();
- ALOGV("%s: pcm_prepare start", __func__);
- pcm_prepare(in->pcm);
- ALOGV("%s: exit", __func__);
+ ALOGD("%s: exit", __func__);
return ret;
@@ -1167,6 +1173,20 @@
return ret;
}
+void lock_input_stream(struct stream_in *in)
+{
+ pthread_mutex_lock(&in->pre_lock);
+ pthread_mutex_lock(&in->lock);
+ pthread_mutex_unlock(&in->pre_lock);
+}
+
+void lock_output_stream(struct stream_out *out)
+{
+ pthread_mutex_lock(&out->pre_lock);
+ pthread_mutex_lock(&out->lock);
+ pthread_mutex_unlock(&out->pre_lock);
+}
+
/* must be called with out->lock locked */
static int send_offload_cmd_l(struct stream_out* out, int command)
{
@@ -1255,7 +1275,7 @@
prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
for (;;) {
struct offload_cmd *cmd = NULL;
stream_callback_event_t event;
@@ -1334,7 +1354,7 @@
ALOGE("%s unknown command received: %d", __func__, cmd->cmd);
break;
}
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
out->offload_thread_blocked = false;
pthread_cond_signal(&out->cond);
if (send_callback && out->offload_callback) {
@@ -1366,7 +1386,7 @@
static int destroy_offload_callback_thread(struct stream_out *out)
{
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
stop_compressed_output_l(out);
send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);
@@ -1629,10 +1649,16 @@
platform_set_stream_channel_map(adev->platform, out->channel_mask,
out->pcm_device_id);
- ALOGV("%s: pcm_prepare start", __func__);
- if (pcm_is_ready(out->pcm))
- pcm_prepare(out->pcm);
-
+ ALOGV("%s: pcm_prepare", __func__);
+ if (pcm_is_ready(out->pcm)) {
+ ret = pcm_prepare(out->pcm);
+ if (ret < 0) {
+ ALOGE("%s: pcm_prepare returned %d", __func__, ret);
+ pcm_close(out->pcm);
+ out->pcm = NULL;
+ goto error_open;
+ }
+ }
} else {
platform_set_stream_channel_map(adev->platform, out->channel_mask,
out->pcm_device_id);
@@ -1679,7 +1705,7 @@
}
}
- ALOGV("%s: exit", __func__);
+ ALOGD("%s: exit", __func__);
return 0;
error_open:
@@ -1819,7 +1845,7 @@
return 0;
}
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (!out->standby) {
if (adev->adm_deregister_stream)
adev->adm_deregister_stream(adev->adm_data, out->handle);
@@ -1908,7 +1934,7 @@
err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
if (err >= 0) {
val = atoi(value);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
pthread_mutex_lock(&adev->lock);
/*
@@ -1972,7 +1998,7 @@
pthread_mutex_unlock(&adev->lock);
}
if (is_offload_usecase(out->usecase)) {
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
parse_compress_metadata(out, parms);
audio_extn_dts_create_state_notifier_node(out->usecase);
@@ -2128,7 +2154,7 @@
int snd_scard_state = get_snd_card_state(adev);
ssize_t ret = 0;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (SND_CARD_STATE_OFFLINE == snd_scard_state) {
// increase written size during SSR to avoid mismatch
@@ -2273,7 +2299,7 @@
*dsp_frames = 0;
if (is_offload_usecase(out->usecase)) {
ssize_t ret = 0;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->compr != NULL) {
ret = compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
&out->sample_rate);
@@ -2332,7 +2358,7 @@
int ret = -1;
unsigned long dsp_frames;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (is_offload_usecase(out->usecase)) {
if (out->compr != NULL) {
@@ -2384,7 +2410,7 @@
struct stream_out *out = (struct stream_out *)stream;
ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
out->offload_callback = callback;
out->offload_cookie = cookie;
pthread_mutex_unlock(&out->lock);
@@ -2398,7 +2424,7 @@
ALOGV("%s", __func__);
if (is_offload_usecase(out->usecase)) {
ALOGD("copl(%p):pause compress driver", out);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
struct audio_device *adev = out->dev;
int snd_scard_state = get_snd_card_state(adev);
@@ -2426,7 +2452,7 @@
if (is_offload_usecase(out->usecase)) {
ALOGD("copl(%p):resume compress driver", out);
status = 0;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
struct audio_device *adev = out->dev;
int snd_scard_state = get_snd_card_state(adev);
@@ -2451,7 +2477,7 @@
int status = -ENOSYS;
ALOGV("%s", __func__);
if (is_offload_usecase(out->usecase)) {
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (type == AUDIO_DRAIN_EARLY_NOTIFY)
status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
else
@@ -2467,7 +2493,7 @@
ALOGV("%s", __func__);
if (is_offload_usecase(out->usecase)) {
ALOGD("copl(%p):calling compress flush", out);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
stop_compressed_output_l(out);
pthread_mutex_unlock(&out->lock);
ALOGD("copl(%p):out of compress flush", out);
@@ -2539,7 +2565,7 @@
return status;
}
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
if (!in->standby && in->is_st_session) {
ALOGD("%s: sound trigger pcm stop lab", __func__);
audio_extn_sound_trigger_stop_lab(in);
@@ -2584,7 +2610,7 @@
if (!parms)
goto error;
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
pthread_mutex_lock(&adev->lock);
err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
@@ -2668,7 +2694,7 @@
int i, ret = -1;
int snd_scard_state = get_snd_card_state(adev);
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
if (in->is_st_session) {
ALOGVV(" %s: reading on st session bytes=%zu", __func__, bytes);
@@ -2768,7 +2794,7 @@
if (status != 0)
return status;
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
pthread_mutex_lock(&in->dev->lock);
if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
in->enable_aec != enable &&
@@ -2836,6 +2862,7 @@
}
pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
if (devices == AUDIO_DEVICE_NONE)
@@ -3502,6 +3529,7 @@
devices, &in->stream, handle, source);
pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
in->stream.common.get_sample_rate = in_get_sample_rate;
in->stream.common.set_sample_rate = in_set_sample_rate;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 15ec582..85be217 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -183,6 +183,7 @@
struct stream_out {
struct audio_stream_out stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
pthread_cond_t cond;
struct pcm_config config;
struct compr_config compr_config;
@@ -227,6 +228,7 @@
struct stream_in {
struct audio_stream_in stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
struct pcm_config config;
struct pcm *pcm;
int standby;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 7357828..976cfe9 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -143,7 +143,7 @@
#define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
-#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED "is_hw_dec_session_allowed"
+#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_AVAILABLE "is_hw_dec_session_available"
#define MAX_DSP_ONLY_DECODERS 6
@@ -3561,7 +3561,7 @@
}
native_audio_get_params(query, reply, value, sizeof(value));
- ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED,
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_AVAILABLE,
value, sizeof(value));
if (ret >= 0) {
int isallowed = 1; /*true*/
@@ -3588,7 +3588,7 @@
}
}
}
- str_parms_add_int(reply, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED, isallowed);
+ str_parms_add_int(reply, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_AVAILABLE, isallowed);
}
diff --git a/hal/voice.c b/hal/voice.c
index 527856f..bc9d5c7 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -131,8 +131,7 @@
}
session->state.current = CALL_INACTIVE;
- if (adev->mode == AUDIO_MODE_NORMAL)
- adev->voice.is_in_call = false;
+ adev->voice.is_in_call = false;
/* Disable sidetone only when no calls are active */
if (!voice_is_call_state_active(adev))
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index a4a3d04..6a73925 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>
@@ -460,6 +456,14 @@
ALOGV("isOffloadSupported: has_video == true, returning false");
return false;
}
+
+ const bool allowOffloadStreamingWithVideo = property_get_bool("av.streaming.offload.enable",
+ false /*default value*/);
+ if(offloadInfo.has_video && offloadInfo.is_streaming && !allowOffloadStreamingWithVideo) {
+ ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue );
+ return false;
+ }
+
}
//If duration is less than minimum value defined in property, return false
@@ -596,7 +600,7 @@
/// Opens: can these line be executed after the switch of volume curves???
// if leaving call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
- if (isInCall()) {
+ if (isStateInCall(oldState)) {
ALOGV("setPhoneState() in call state management: new state is %d", state);
for (size_t j = 0; j < mOutputs.size(); j++) {
audio_io_handle_t curOutput = mOutputs.keyAt(j);
@@ -845,9 +849,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()) {
@@ -1962,8 +1963,8 @@
void AudioPolicyManagerCustom::closeAllInputs() {
bool patchRemoved = false;
- for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
- sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
+ for(size_t input_index = mInputs.size(); input_index > 0; input_index--) {
+ sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index-1);
ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
if (patch_index >= 0) {
sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
@@ -1974,8 +1975,8 @@
if ((inputDesc->mIsSoundTrigger) && (mInputs.size() == 1)) {
ALOGD("Do not close sound trigger input handle");
} else {
- mpClientInterface->closeInput(mInputs.keyAt(input_index));
- mInputs.removeItem(mInputs.keyAt(input_index));
+ mpClientInterface->closeInput(mInputs.keyAt(input_index-1));
+ mInputs.removeItem(mInputs.keyAt(input_index-1));
}
}
nextAudioPortGeneration();