From e36bd73d88ae702b71a4d602fb0d863706dfbc94 Mon Sep 17 00:00:00 2001 From: Piyush Balwani Date: Mon, 8 Apr 2019 17:11:56 +0530 Subject: audiopolicy: align custom APM with AOSP. Change-Id: Ic5112352c5aa1bcc9e889cca76048b6b27b2c4c6 --- policy_hal/AudioPolicyManager.cpp | 110 +++++++++++++++++++++----------------- policy_hal/AudioPolicyManager.h | 15 +++--- 2 files changed, 69 insertions(+), 56 deletions(-) diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp index 3aff1d0..3885491 100644 --- a/policy_hal/AudioPolicyManager.cpp +++ b/policy_hal/AudioPolicyManager.cpp @@ -265,10 +265,11 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d && strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) { for (audio_io_handle_t output : outputs) { sp desc = mOutputs.valueFor(output); - if (desc->mPolicyMix != nullptr - && desc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS + sp policyMix = desc->mPolicyMix.promote(); + if (policyMix != nullptr + && policyMix->mMixType == MIX_TYPE_RECORDERS && strncmp(device_address, - desc->mPolicyMix->mDeviceAddress.string(), + policyMix->mDeviceAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { doCheckForDeviceAndOutputChanges = false; break; @@ -1040,12 +1041,13 @@ status_t AudioPolicyManagerCustom::stopSource(const sp& if (outputDesc->getActivityCount(clientVolSrc) == 1) { // Automatically disable the remote submix input when output is stopped on a // re routing mix of type MIX_TYPE_RECORDERS + sp policyMix = outputDesc->mPolicyMix.promote(); if (audio_is_remote_submix_device(outputDesc->devices().types()) && - outputDesc->mPolicyMix != NULL && - outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { + policyMix != NULL && + policyMix->mMixType == MIX_TYPE_RECORDERS) { setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, - outputDesc->mPolicyMix->mDeviceAddress, + policyMix->mDeviceAddress, "remote-submix", AUDIO_FORMAT_DEFAULT); } } @@ -1153,10 +1155,9 @@ status_t AudioPolicyManagerCustom::startSource(const sp (outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE); DeviceVector devices; - AudioMix *policyMix = NULL; + sp policyMix = outputDesc->mPolicyMix.promote(); const char *address = NULL; - if (outputDesc->mPolicyMix != NULL) { - policyMix = outputDesc->mPolicyMix; + if (policyMix != NULL) { audio_devices_t newDeviceType; address = policyMix->mDeviceAddress.string(); if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) { @@ -1244,7 +1245,8 @@ status_t AudioPolicyManagerCustom::startSource(const sp setOutputDevices(outputDesc, devices, force, 0, NULL, requiresMuteCheck); // apply volume rules for current stream and device if necessary - checkAndSetVolume(stream, + auto &curves = getVolumeCurves(client->attributes()); + checkAndSetVolume(curves, client->volumeSource(), getVolumeCurves(stream).getVolumeIndex(outputDesc->devices().types()), outputDesc, outputDesc->devices().types()); @@ -1282,29 +1284,34 @@ status_t AudioPolicyManagerCustom::startSource(const sp return NO_ERROR; } -status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream, - int index, - const sp& outputDesc, - audio_devices_t device, - int delayMs, - bool force) +status_t AudioPolicyManagerCustom::checkAndSetVolume(IVolumeCurves &curves, + VolumeSource volumeSource, + int index, + const sp& outputDesc, + audio_devices_t device, + int delayMs, + bool force) { - if (stream < 0 || stream >= AUDIO_STREAM_CNT) { - ALOGW("checkAndSetVolume() invalid stream %d", stream); - return INVALID_OPERATION; - } // do not change actual stream volume if the stream is muted - if (outputDesc->isMuted(streamToVolumeSource(stream))) { - ALOGVV("%s() stream %d muted count %d", __func__, stream, outputDesc->getMuteCount(stream)); + if (outputDesc->isMuted(volumeSource)) { + ALOGVV("%s: volume source %d muted count %d active=%d", __func__, volumeSource, + outputDesc->getMuteCount(volumeSource), outputDesc->isActive(volumeSource)); return NO_ERROR; } + + VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL); + VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO); + bool isVoiceVolSrc = callVolSrc == volumeSource; + bool isBtScoVolSrc = btScoVolSrc == volumeSource; + audio_policy_forced_cfg_t forceUseForComm = mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION); // do not change in call volume if bluetooth is connected and vice versa - if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) || - (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) { + if ((callVolSrc != btScoVolSrc) && + ((isVoiceVolSrc && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) || + (isBtScoVolSrc && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO))) { ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", - stream, forceUseForComm); + volumeSource, forceUseForComm); return INVALID_OPERATION; } @@ -1312,19 +1319,18 @@ status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream, device = outputDesc->devices().types(); } - float volumeDb = computeVolume(stream, index, device); + float volumeDb = computeVolume(curves, volumeSource, index, device); if (outputDesc->isFixedVolume(device)) { volumeDb = 0.0f; } - outputDesc->setVolume(volumeDb, stream, device, delayMs, force); + outputDesc->setVolume(volumeDb, volumeSource, curves.getStreamTypes(), device, delayMs, force); - if (stream == AUDIO_STREAM_VOICE_CALL || - stream == AUDIO_STREAM_BLUETOOTH_SCO) { + if (isVoiceVolSrc || isBtScoVolSrc) { float voiceVolume; // Force voice volume to max for bluetooth SCO as volume is managed by the headset - if (stream == AUDIO_STREAM_VOICE_CALL) { - voiceVolume = (float)index/(float)getVolumeCurves(stream).getVolumeIndexMax(); + if (isVoiceVolSrc) { + voiceVolume = (float)index/(float)curves.getVolumeIndexMax(); } else { voiceVolume = 1.0; } @@ -1389,15 +1395,20 @@ status_t AudioPolicyManagerCustom::getOutputForAttr(const audio_attributes_t *at } audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( - const DeviceVector &devices, - audio_session_t session, - audio_stream_type_t stream, - const audio_config_t *config, - audio_output_flags_t *flags) + const DeviceVector &devices, + audio_session_t session, + audio_stream_type_t stream, + const audio_config_t *config, + audio_output_flags_t *flags, + bool forceMutingHaptic) { audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; status_t status; + // Discard haptic channel mask when forcing muting haptic channels. + audio_channel_mask_t channelMask = forceMutingHaptic + ? (config->channel_mask & ~AUDIO_CHANNEL_HAPTIC_ALL) : config->channel_mask; + if (stream < AUDIO_STREAM_MIN || stream >= AUDIO_STREAM_CNT) { ALOGE("%s: invalid stream %d", __func__, stream); return AUDIO_IO_HANDLE_NONE; @@ -1417,7 +1428,7 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( // in case direct voip is bypassed bool use_primary_out = true; - if ((config->channel_mask == 1) && + if ((channelMask == 1) && (config->sample_rate == 8000 || config->sample_rate == 16000 || config->sample_rate == 32000 || config->sample_rate == 48000)) { // Allow Voip direct output only if: @@ -1695,7 +1706,7 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( // and not explicitly requested if (((*flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) && audio_is_linear_pcm(config->format) && config->sample_rate <= SAMPLE_RATE_HZ_MAX && - audio_channel_count_from_out_mask(config->channel_mask) <= 2) { + audio_channel_count_from_out_mask(channelMask) <= 2) { goto non_direct_output; } @@ -1718,7 +1729,7 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( profile = getProfileForOutput(devices, config->sample_rate, config->format, - config->channel_mask, + channelMask, (audio_output_flags_t)*flags, true /* directOnly */); @@ -1746,7 +1757,7 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( // and configured with same parameters if ((config->sample_rate == desc->mSamplingRate) && audio_formats_match(config->format, desc->mFormat) && - (config->channel_mask == desc->mChannelMask) && + (channelMask == desc->mChannelMask) && (session == desc->mDirectClientSession)) { desc->mDirectOpenCount++; ALOGV("getOutputForDevice() reusing direct output %d for session %d", @@ -1782,11 +1793,11 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( (config->sample_rate != 0 && config->sample_rate != outputDesc->mSamplingRate) || (config->format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(config->format, outputDesc->mFormat)) || - (config->channel_mask != 0 && config->channel_mask != outputDesc->mChannelMask)) { + (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { ALOGV("getOutputForDevice() failed opening direct output: output %d sample rate %d %d," "format %d %d, channel mask %04x %04x", output, config->sample_rate, outputDesc->mSamplingRate, config->format, outputDesc->mFormat, - config->channel_mask, outputDesc->mChannelMask); + channelMask, outputDesc->mChannelMask); if (output != AUDIO_IO_HANDLE_NONE) { outputDesc->close(); } @@ -1843,7 +1854,7 @@ non_direct_output: ALOGW_IF((output == 0), "getOutputForDevice() could not find output for stream %d, " "sampling rate %d, format %#x, channels %#x, flags %#x", - stream, config->sample_rate, config->format, config->channel_mask, *flags); + stream, config->sample_rate, config->format, channelMask, *flags); ALOGV("getOutputForDevice() returns output %d", output); @@ -2029,10 +2040,11 @@ status_t AudioPolicyManagerCustom::startInput(audio_port_handle_t portId) setInputDevice(input, device, true /* force */); if (inputDesc->activeCount() == 1) { + sp policyMix = inputDesc->mPolicyMix.promote(); // if input maps to a dynamic policy with an activity listener, notify of state change - if ((inputDesc->mPolicyMix != NULL) - && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) { - mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress, + if ((policyMix != NULL) + && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) { + mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress, MIX_STATE_MIXING); } @@ -2050,10 +2062,10 @@ status_t AudioPolicyManagerCustom::startInput(audio_port_handle_t portId) // For remote submix (a virtual device), we open only one input per capture request. if (audio_is_remote_submix_device(inputDesc->getDeviceType())) { String8 address = String8(""); - if (inputDesc->mPolicyMix == NULL) { + if (policyMix == NULL) { address = String8("0"); - } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { - address = inputDesc->mPolicyMix->mDeviceAddress; + } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) { + address = policyMix->mDeviceAddress; } if (address != "") { setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h index 96d7dcb..5a8a907 100644 --- a/policy_hal/AudioPolicyManager.h +++ b/policy_hal/AudioPolicyManager.h @@ -115,11 +115,12 @@ public: static sp mApmConfigs; protected: - status_t checkAndSetVolume(audio_stream_type_t stream, - int index, - const sp& outputDesc, - audio_devices_t device, - int delayMs = 0, bool force = false); + // check that volume change is permitted, compute and send new volume to audio hardware + virtual status_t checkAndSetVolume(IVolumeCurves &curves, + VolumeSource volumeSource, int index, + const sp& outputDesc, + audio_devices_t device, + int delayMs = 0, bool force = false); // avoid invalidation for active music stream on previous outputs // which is supported on the new device. @@ -156,8 +157,8 @@ private: audio_session_t session, audio_stream_type_t stream, const audio_config_t *config, - audio_output_flags_t *flags); - + audio_output_flags_t *flags, + bool forceMutingHaptic = false); // internal method to fill offload info in case of Direct PCM status_t getOutputForAttr(const audio_attributes_t *attr, -- cgit v1.2.3