Merge "Merge commit '50650f44fd1c18620bc39a4458f38974eef61402' into private_redfox64_mbr."
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index c3dbecc..512a584 100755
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -177,6 +177,7 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
#endif
+ [USECASE_AUDIO_PLAYBACK_ULL] = "audio-ull-playback",
[USECASE_AUDIO_RECORD] = "audio-record",
[USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
[USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
@@ -1139,7 +1140,10 @@
}
audio_extn_perf_lock_release();
+ ALOGV("%s: pcm_prepare start", __func__);
+ pcm_prepare(in->pcm);
ALOGV("%s: exit", __func__);
+
return ret;
error_open:
@@ -1607,8 +1611,14 @@
}
break;
}
+
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);
+
} else {
platform_set_stream_channel_map(adev->platform, out->channel_mask,
out->pcm_device_id);
@@ -1651,7 +1661,9 @@
audio_extn_check_and_set_dts_hpx_state(adev);
}
}
+
ALOGV("%s: exit", __func__);
+
return 0;
error_open:
stop_output_stream(out);
@@ -1787,6 +1799,9 @@
pthread_mutex_lock(&out->lock);
if (!out->standby) {
+ if (adev->adm_deregister_stream)
+ adev->adm_deregister_stream(adev->adm_data, out->handle);
+
pthread_mutex_lock(&adev->lock);
out->standby = true;
if (!is_offload_usecase(out->usecase)) {
@@ -2139,6 +2154,8 @@
out->standby = true;
goto exit;
}
+ if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD && adev->adm_register_output_stream)
+ adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
}
if (adev->mChannelStatusSet == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){
@@ -2184,15 +2201,24 @@
if (out->pcm) {
if (out->muted)
memset((void *)buffer, 0, bytes);
+
ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
+
+ if (adev->adm_request_focus)
+ adev->adm_request_focus(adev->adm_data, out->handle);
+
if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY)
ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
else
ret = pcm_write(out->pcm, (void *)buffer, bytes);
+
if (ret < 0)
ret = -errno;
else if (ret == 0)
out->written += bytes / (out->config.channels * sizeof(short));
+
+ if (adev->adm_abandon_focus)
+ adev->adm_abandon_focus(adev->adm_data, out->handle);
}
}
@@ -2508,6 +2534,9 @@
}
if (!in->standby) {
+ if (adev->adm_deregister_stream)
+ adev->adm_deregister_stream(adev->adm_data, in->capture_handle);
+
pthread_mutex_lock(&adev->lock);
in->standby = true;
if (in->pcm) {
@@ -2653,8 +2682,13 @@
goto exit;
}
in->standby = 0;
+ if (adev->adm_register_input_stream)
+ adev->adm_register_input_stream(adev->adm_data, in->capture_handle, in->flags);
}
+ if (adev->adm_request_focus)
+ adev->adm_request_focus(adev->adm_data, in->capture_handle);
+
if (in->pcm) {
if (audio_extn_ssr_get_enabled() &&
audio_channel_count_from_in_mask(in->channel_mask) == 6)
@@ -2669,6 +2703,9 @@
ret = -errno;
}
+ if (adev->adm_abandon_focus)
+ adev->adm_abandon_focus(adev->adm_data, in->capture_handle);
+
/*
* Instead of writing zeroes here, we could trust the hardware
* to always provide zeroes when muted.
@@ -2988,6 +3025,10 @@
out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY;
out->config = pcm_config_afe_proxy_playback;
adev->voice_tx_output = out;
+ } else if (out->flags & AUDIO_OUTPUT_FLAG_RAW) {
+ out->usecase = USECASE_AUDIO_PLAYBACK_ULL;
+ out->config = pcm_config_low_latency;
+ out->sample_rate = out->config.rate;
} else if (out->flags & AUDIO_OUTPUT_FLAG_FAST) {
format = AUDIO_FORMAT_PCM_16_BIT;
out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
@@ -3457,6 +3498,7 @@
in->standby = 1;
in->channel_mask = config->channel_mask;
in->capture_handle = handle;
+ in->flags = flags;
/* Update config params with the requested sample rate and channels */
in->usecase = USECASE_AUDIO_RECORD;
@@ -3599,10 +3641,13 @@
audio_route_free(adev->audio_route);
free(adev->snd_dev_ref_cnt);
platform_deinit(adev->platform);
+ if (adev->adm_deinit)
+ adev->adm_deinit(adev->adm_data);
free(device);
adev = NULL;
}
pthread_mutex_unlock(&adev_init_lock);
+
return 0;
}
@@ -3614,6 +3659,7 @@
{
switch (period_size) {
case 160:
+ case 192:
case 240:
case 320:
case 480:
@@ -3747,6 +3793,29 @@
}
}
+ if (access(ADM_LIBRARY_PATH, R_OK) == 0) {
+ adev->adm_lib = dlopen(ADM_LIBRARY_PATH, RTLD_NOW);
+ if (adev->adm_lib == NULL) {
+ ALOGE("%s: DLOPEN failed for %s", __func__, ADM_LIBRARY_PATH);
+ } else {
+ ALOGV("%s: DLOPEN successful for %s", __func__, ADM_LIBRARY_PATH);
+ adev->adm_init = (adm_init_t)
+ dlsym(adev->adm_lib, "adm_init");
+ adev->adm_deinit = (adm_deinit_t)
+ dlsym(adev->adm_lib, "adm_deinit");
+ adev->adm_register_input_stream = (adm_register_input_stream_t)
+ dlsym(adev->adm_lib, "adm_register_input_stream");
+ adev->adm_register_output_stream = (adm_register_output_stream_t)
+ dlsym(adev->adm_lib, "adm_register_output_stream");
+ adev->adm_deregister_stream = (adm_deregister_stream_t)
+ dlsym(adev->adm_lib, "adm_deregister_stream");
+ adev->adm_request_focus = (adm_request_focus_t)
+ dlsym(adev->adm_lib, "adm_request_focus");
+ adev->adm_abandon_focus = (adm_abandon_focus_t)
+ dlsym(adev->adm_lib, "adm_abandon_focus");
+ }
+ }
+
adev->bt_wb_speech_enabled = false;
audio_extn_ds2_enable(adev);
@@ -3777,6 +3846,9 @@
pthread_mutex_unlock(&adev_init_lock);
+ if (adev->adm_init)
+ adev->adm_data = adev->adm_init();
+
ALOGV("%s: exit", __func__);
return 0;
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index f01d38d..983a89e 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -49,6 +49,7 @@
#define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so"
#define OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH "/system/lib/soundfx/libqcompostprocbundle.so"
+#define ADM_LIBRARY_PATH "/system/vendor/lib/libadm.so"
/* Flags used to initialize acdb_settings variable that goes to ACDB library */
#define NONE_FLAG 0x00000000
@@ -93,6 +94,7 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD8,
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
#endif
+ USECASE_AUDIO_PLAYBACK_ULL,
/* FM usecase */
USECASE_AUDIO_PLAYBACK_FM,
@@ -233,6 +235,7 @@
bool enable_ns;
audio_format_t format;
audio_io_handle_t capture_handle;
+ audio_input_flags_t flags;
bool is_st_session;
bool is_st_session_active;
@@ -285,6 +288,14 @@
struct stream_app_type_cfg app_type_cfg;
};
+typedef void* (*adm_init_t)();
+typedef void (*adm_deinit_t)(void *);
+typedef void (*adm_register_output_stream_t)(void *, audio_io_handle_t, audio_output_flags_t);
+typedef void (*adm_register_input_stream_t)(void *, audio_io_handle_t, audio_input_flags_t);
+typedef void (*adm_deregister_stream_t)(void *, audio_io_handle_t);
+typedef void (*adm_request_focus_t)(void *, audio_io_handle_t);
+typedef void (*adm_abandon_focus_t)(void *, audio_io_handle_t);
+
struct audio_device {
struct audio_hw_device device;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
@@ -326,6 +337,16 @@
void (*offload_effects_get_parameters)(struct str_parms *,
struct str_parms *);
void (*offload_effects_set_parameters)(struct str_parms *);
+
+ void *adm_data;
+ void *adm_lib;
+ adm_init_t adm_init;
+ adm_deinit_t adm_deinit;
+ adm_register_input_stream_t adm_register_input_stream;
+ adm_register_output_stream_t adm_register_output_stream;
+ adm_deregister_stream_t adm_deregister_stream;
+ adm_request_focus_t adm_request_focus;
+ adm_abandon_focus_t adm_abandon_focus;
};
int select_devices(struct audio_device *adev,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index b7ffde3..c0aa2a1 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -281,6 +281,7 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
#endif
+ [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE, MULTIMEDIA3_PCM_DEVICE},
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
[USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -664,6 +665,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
#endif
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index bf5e834..5d0ad2d 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -236,6 +236,7 @@
#define DEEP_BUFFER_PCM_DEVICE 0
#define AUDIO_RECORD_PCM_DEVICE 0
#define MULTIMEDIA2_PCM_DEVICE 1
+#define MULTIMEDIA3_PCM_DEVICE 4
#define FM_PLAYBACK_PCM_DEVICE 5
#define FM_CAPTURE_PCM_DEVICE 6
#define HFP_PCM_RX 5
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 2b9608c..65dd01f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -224,7 +224,7 @@
[USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
LOWLATENCY_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
- MULTIMEDIA2_PCM_DEVICE},
+ MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
#ifdef MULTIPLE_OFFLOAD_ENABLED
@@ -245,6 +245,9 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
{PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
#endif
+ [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE,
+ MULTIMEDIA3_PCM_DEVICE},
+
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
[USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -596,6 +599,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
#endif
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 79e0816..4787b86 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -217,6 +217,7 @@
#define DEEP_BUFFER_PCM_DEVICE 0
#define AUDIO_RECORD_PCM_DEVICE 0
#define MULTIMEDIA2_PCM_DEVICE 1
+#define MULTIMEDIA3_PCM_DEVICE 4
#define FM_PLAYBACK_PCM_DEVICE 5
#define FM_CAPTURE_PCM_DEVICE 6
#define HFP_PCM_RX 5
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index a638c1d..17b7135 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -907,6 +907,53 @@
mLimitRingtoneVolume = false;
}
}
+
+void AudioPolicyManagerCustom::setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config)
+{
+ ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
+
+ if (mEngine->setForceUse(usage, config) != NO_ERROR) {
+ ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
+ return;
+ }
+ bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
+ (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
+ (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
+
+ // check for device and output changes triggered by new force usage
+ checkA2dpSuspend();
+ checkOutputForAllStrategies();
+ updateDevicesAndOutputs();
+ if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
+ audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
+ updateCallRouting(newDevice);
+ }
+ // Use reverse loop to make sure any low latency usecases (generally tones)
+ // are not routed before non LL usecases (generally music).
+ // We can safely assume that LL output would always have lower index,
+ // and use this work-around to avoid routing of output with music stream
+ // from the context of short lived LL output.
+ // Note: in case output's share backend(HAL sharing is implicit) all outputs
+ // gets routing update while processing first output itself.
+ for (size_t i = mOutputs.size(); i > 0; i--) {
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i-1);
+ audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
+ if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || outputDesc != mPrimaryOutput) {
+ setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE));
+ }
+ if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
+ applyStreamVolumes(outputDesc, newDevice, 0, true);
+ }
+ }
+
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0) {
+ setInputDevice(activeInput, getNewInputDevice(activeInput));
+ }
+
+}
+
status_t AudioPolicyManagerCustom::stopSource(sp<SwAudioOutputDescriptor> outputDesc,
audio_stream_type_t stream,
bool forceDeviceUpdate)
@@ -1816,6 +1863,32 @@
return status;
}
+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);
+ ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
+ if (patch_index >= 0) {
+ sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
+ status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
+ mAudioPatches.removeItemsAt(patch_index);
+ patchRemoved = true;
+ }
+ 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));
+ }
+ }
+ nextAudioPortGeneration();
+
+ if (patchRemoved) {
+ mpClientInterface->onAudioPatchListUpdate();
+ }
+}
+
AudioPolicyManagerCustom::AudioPolicyManagerCustom(AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface),
mHdmiAudioDisabled(false),
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 53c9a1b..66f9c38 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -54,6 +54,8 @@
const char *device_address,
const char *device_name);
virtual void setPhoneState(audio_mode_t state);
+ virtual void setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config);
virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
@@ -73,6 +75,7 @@
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input,
audio_session_t session);
+ virtual void closeAllInputs();
protected: