diff options
author | Vara Prasad A V S G <vavsg@codeaurora.org> | 2019-04-10 16:47:24 +0530 |
---|---|---|
committer | Vara Prasad A V S G <vavsg@codeaurora.org> | 2019-04-10 16:47:24 +0530 |
commit | d6aaa538d2960e2157b76f01f090f2b226eca02f (patch) | |
tree | 7bb59682b8680f24306dd8d2764bf0b234a49abb | |
parent | 834c8148dfdb10e0915c16babaae96b0577aec7e (diff) | |
parent | 0a3c0b41caff5ac7e943701e62c93979a5cb3dd8 (diff) | |
download | android_vendor_qcom_opensource_audio-d6aaa538d2960e2157b76f01f090f2b226eca02f.tar.gz android_vendor_qcom_opensource_audio-d6aaa538d2960e2157b76f01f090f2b226eca02f.tar.bz2 android_vendor_qcom_opensource_audio-d6aaa538d2960e2157b76f01f090f2b226eca02f.zip |
Merge commit '0a3c0b41caff5ac7e943701e62c93979a5cb3dd8' into HEAD
Conflicts:
policy_hal/AudioPolicyManager.cpp
policy_hal/AudioPolicyManager.h
Change-Id: I3402ff9fb16a546429834473c32da7276a4ec2ba
-rwxr-xr-x[-rw-r--r--] | policy_hal/AudioPolicyManager.cpp | 268 | ||||
-rwxr-xr-x[-rw-r--r--] | policy_hal/AudioPolicyManager.h | 6 |
2 files changed, 155 insertions, 119 deletions
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp index 345f9e4..b3126d6 100644..100755 --- a/policy_hal/AudioPolicyManager.cpp +++ b/policy_hal/AudioPolicyManager.cpp @@ -82,14 +82,6 @@ audio_output_flags_t AudioPolicyManagerCustom::getFallBackPath() return flag; } -void AudioPolicyManagerCustom::moveGlobalEffect() -{ - audio_io_handle_t dstOutput = getOutputForEffect(); - if (hasPrimaryOutput() && dstOutput != mPrimaryOutput->mIoHandle) - mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, - mPrimaryOutput->mIoHandle, dstOutput); -} - // ---------------------------------------------------------------------------- // AudioPolicyInterface implementation // ---------------------------------------------------------------------------- @@ -110,7 +102,7 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d const char *device_name, audio_format_t encodedFormat) { - ALOGD("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s encodedFormat = 0x%X", + ALOGD("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s format 0x%X", deviceType, state, device_address, device_name, encodedFormat); // connect/disconnect only 1 device at a time @@ -119,6 +111,9 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d sp<DeviceDescriptor> device = mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat, state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE); + if (device == 0) { + return INVALID_OPERATION; + } // handle output devices if (audio_is_output_device(deviceType)) { @@ -145,7 +140,8 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d ALOGW("setDeviceConnectionState() device already connected: %x", deviceType); return INVALID_OPERATION; } - ALOGV("setDeviceConnectionState() connecting device %x", deviceType); + ALOGV("%s() connecting device %s format %x", + __func__, device->toString().c_str(), encodedFormat); // register new device as available index = mAvailableOutputDevices.add(device); @@ -165,8 +161,8 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d if (index >= 0) { sp<HwModule> module = mHwModules.getModuleForDevice(device, encodedFormat); if (module == 0) { - ALOGD("setDeviceConnectionState() could not find HW module for device %08x", - deviceType); + ALOGD("setDeviceConnectionState() could not find HW module for device %s", + device->toString().c_str()); mAvailableOutputDevices.remove(device); return INVALID_OPERATION; } @@ -183,6 +179,8 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) { mAvailableOutputDevices.remove(device); + mHwModules.cleanUpForDevice(device); + broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE); return INVALID_OPERATION; } @@ -199,8 +197,7 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d // outputs should never be empty here ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():" "checkOutputsForDevice() returned no outputs but status OK"); - ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs", - outputs.size()); + ALOGV("%s() checkOutputsForDevice() returned %zu outputs", __func__, outputs.size()); } break; // handle output device disconnection @@ -218,13 +215,15 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d return INVALID_OPERATION; } - ALOGV("setDeviceConnectionState() disconnecting output device %x", deviceType); + ALOGV("%s() disconnecting output device %s", __func__, device->toString().c_str()); // Send Disconnect to HALs broadcastDeviceConnectionState(device, state); // remove device from available output devices mAvailableOutputDevices.remove(device); + + mOutputs.clearSessionRoutesForDevice(device); if (mApmConfigs->isHDMISpkEnabled() && (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) { if (!strncmp(device_address, "hdmi_spkr", 9)) { @@ -250,14 +249,10 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d } break; default: - ALOGE("setDeviceConnectionState() invalid state: %x", state); + ALOGE("%s() invalid state: %x", __func__, state); return BAD_VALUE; } - // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP - // output is suspended before any tracks are moved to it - checkA2dpSuspend(); - if (!outputs.isEmpty()) { for (size_t i = 0; i < outputs.size(); i++) { sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); @@ -270,21 +265,48 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d } } - checkOutputForAllStrategies(); - // outputs must be closed after checkOutputForAllStrategies() is executed - if (!outputs.isEmpty()) { - for (size_t i = 0; i < outputs.size(); i++) { - sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); - // close unused outputs after device disconnection or direct outputs that have been - // opened by checkOutputsForDevice() to query dynamic parameters - if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) || - (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && - (desc->mDirectOpenCount == 0))) { - closeOutput(outputs[i]); + // No need to evaluate playback routing when connecting a remote submix + // output device used by a dynamic policy of type recorder as no + // playback use case is affected. + bool doCheckForDeviceAndOutputChanges = true; + if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX + && strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) { + for (audio_io_handle_t output : outputs) { + sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output); + if (desc->mPolicyMix != nullptr + && desc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS + && strncmp(device_address, + desc->mPolicyMix->mDeviceAddress.string(), + AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { + doCheckForDeviceAndOutputChanges = false; + break; } } - // check again after closing A2DP output to reset mA2dpSuspended if needed - checkA2dpSuspend(); + } + + auto checkCloseOutputs = [&]() { + // outputs must be closed after checkOutputForAllStrategies() is executed + if (!outputs.isEmpty()) { + for (audio_io_handle_t output : outputs) { + sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output); + // close unused outputs after device disconnection or direct outputs that have + // been opened by checkOutputsForDevice() to query dynamic parameters + if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) || + (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) && + (desc->mDirectOpenCount == 0))) { + closeOutput(output); + } + } + // check A2DP again after closing A2DP output to reset mA2dpSuspended if needed + return true; + } + return false; + }; + + if (doCheckForDeviceAndOutputChanges) { + checkForDeviceAndOutputChanges(checkCloseOutputs); + } else { + checkCloseOutputs(); } // handle FM device connection state to trigger FM AFE loopback @@ -341,7 +363,6 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d #endif //TODO CP End - updateDevicesAndOutputs(); if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) { DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/); updateCallRouting(newDevices); @@ -396,6 +417,9 @@ status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t d if (checkInputsForDevice(device, state, inputs) != NO_ERROR) { broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE); + + mHwModules.cleanUpForDevice(device); + return INVALID_OPERATION; } @@ -712,9 +736,7 @@ void AudioPolicyManagerCustom::setPhoneState(audio_mode_t state) || (is_state_in_call(state) && (state != oldState))); // check for device and output changes triggered by new phone state - checkA2dpSuspend(); - checkOutputForAllStrategies(); - updateDevicesAndOutputs(); + checkForDeviceAndOutputChanges(); sp<SwAudioOutputDescriptor> hwOutputDesc = mPrimaryOutput; if (mApmConfigs->isVoiceConcEnabled()) { @@ -992,12 +1014,8 @@ void AudioPolicyManagerCustom::setPhoneState(audio_mode_t state) } // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE - if (state == AUDIO_MODE_RINGTONE && - isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { - mLimitRingtoneVolume = true; - } else { - mLimitRingtoneVolume = false; - } + mLimitRingtoneVolume = (state == AUDIO_MODE_RINGTONE && + isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)); } void AudioPolicyManagerCustom::setForceUse(audio_policy_force_use_t usage, @@ -1017,9 +1035,7 @@ void AudioPolicyManagerCustom::setForceUse(audio_policy_force_use_t usage, (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM); // check for device and output changes triggered by new force usage - checkA2dpSuspend(); - checkOutputForAllStrategies(); - updateDevicesAndOutputs(); + checkForDeviceAndOutputChanges(); /*audio policy: workaround for truncated touch sounds*/ //FIXME: workaround for truncated touch sounds @@ -1056,9 +1072,7 @@ void AudioPolicyManagerCustom::setForceUse(audio_policy_force_use_t usage, } } - Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs(); - for (size_t i = 0; i < activeInputs.size(); i++) { - sp<AudioInputDescriptor> activeDesc = activeInputs[i]; + for (const auto& activeDesc : mInputs.getActiveInputs()) { // Skip for hotword recording as the input device switch // is handled within sound trigger HAL if (activeDesc->isSoundTrigger() && @@ -1079,6 +1093,7 @@ status_t AudioPolicyManagerCustom::stopSource(const sp<SwAudioOutputDescriptor>& const sp<TrackClientDescriptor>& client) { audio_stream_type_t stream = client->stream(); + auto clientVolSrc = client->volumeSource(); if (stream < 0 || stream >= AUDIO_STREAM_CNT) { ALOGW("stopSource() invalid stream %d", stream); @@ -1087,8 +1102,8 @@ status_t AudioPolicyManagerCustom::stopSource(const sp<SwAudioOutputDescriptor>& // always handle stream stop, check which stream type is stopping handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT); - if (outputDesc->streamActiveCount(stream) > 0) { - if (outputDesc->streamActiveCount(stream) == 1) { + if (outputDesc->getActivityCount(clientVolSrc) > 0) { + 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 if (audio_is_remote_submix_device(outputDesc->devices().types()) && @@ -1105,13 +1120,13 @@ status_t AudioPolicyManagerCustom::stopSource(const sp<SwAudioOutputDescriptor>& checkStrategyRoute(client->strategy(), AUDIO_IO_HANDLE_NONE); forceDeviceUpdate = true; } + // decrement usage count of this stream on the output - outputDesc->changeStreamActiveCount(client, -1); - client->setActive(false); + outputDesc->setClientActive(client, false); // store time at which the stream was stopped - see isStreamActive() - if (outputDesc->streamActiveCount(stream) == 0 || forceDeviceUpdate) { - outputDesc->mStopTime[stream] = systemTime(); + if (outputDesc->getActivityCount(clientVolSrc) == 0 || forceDeviceUpdate) { + outputDesc->setStopTime(client, systemTime()); DeviceVector prevDevices = outputDesc->devices(); DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/); // delay the device switch by twice the latency because stopOutput() is executed when @@ -1152,7 +1167,13 @@ status_t AudioPolicyManagerCustom::stopSource(const sp<SwAudioOutputDescriptor>& // update the outputs if stopping one with a stream that can affect notification routing handleNotificationRoutingForStream(stream); } - if (stream == AUDIO_STREAM_MUSIC) { + + if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE && + mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { + setStrategyMute(streamToStrategy(AUDIO_STREAM_RING), false, outputDesc); + } + + if (followsSameRouting(client->attributes(), attributes_initializer(AUDIO_USAGE_MEDIA))) { selectOutputForMusicEffects(); } return NO_ERROR; @@ -1169,6 +1190,8 @@ status_t AudioPolicyManagerCustom::startSource(const sp<SwAudioOutputDescriptor> // cannot start playback of STREAM_TTS if any other output is being used uint32_t beaconMuteLatency = 0; audio_stream_type_t stream = client->stream(); + auto clientVolSrc = client->volumeSource(); + auto clientStrategy = client->strategy(); auto clientAttr = client->attributes(); if (stream < 0 || stream >= AUDIO_STREAM_CNT) { @@ -1179,7 +1202,8 @@ status_t AudioPolicyManagerCustom::startSource(const sp<SwAudioOutputDescriptor> *delayMs = 0; if (stream == AUDIO_STREAM_TTS) { ALOGV("\t found BEACON stream"); - if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) { + if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive( + streamToVolumeSource(AUDIO_STREAM_TTS) /*sourceToIgnore*/)) { return INVALID_OPERATION; } else { beaconMuteLatency = handleEventForBeacon(STARTING_BEACON); @@ -1201,64 +1225,93 @@ status_t AudioPolicyManagerCustom::startSource(const sp<SwAudioOutputDescriptor> policyMix = outputDesc->mPolicyMix; audio_devices_t newDeviceType; address = policyMix->mDeviceAddress.string(); - if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) { - newDeviceType = policyMix->mDeviceType; - } else { + if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) { newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX; + } else { + newDeviceType = policyMix->mDeviceType; } - devices.add(mAvailableOutputDevices.getDevice(newDeviceType, - String8(address), AUDIO_FORMAT_DEFAULT)); + sp device = mAvailableOutputDevices.getDevice(newDeviceType, String8(address), + AUDIO_FORMAT_DEFAULT); + ALOG_ASSERT(device, "%s: no device found t=%u, a=%s", __func__, newDeviceType, address); + devices.add(device); } + // requiresMuteCheck is false when we can bypass mute strategy. + // It covers a common case when there is no materially active audio + // and muting would result in unnecessary delay and dropped audio. + const uint32_t outputLatencyMs = outputDesc->latency(); + bool requiresMuteCheck = outputDesc->isActive(outputLatencyMs * 2); // account for drain + // increment usage count for this stream on the requested output: // NOTE that the usage count is the same for duplicated output and hardware output which is // necessary for a correct control of hardware output routing by startOutput() and stopOutput() - outputDesc->changeStreamActiveCount(client, 1); + outputDesc->setClientActive(client, true); + + if (client->hasPreferredDevice(true)) { + devices = getNewOutputDevices(outputDesc, false /*fromCache*/); + if (devices != outputDesc->devices()) { + checkStrategyRoute(clientStrategy, outputDesc->mIoHandle); + } + } - if (stream == AUDIO_STREAM_MUSIC) { + if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_MEDIA))) { selectOutputForMusicEffects(); } - if (outputDesc->streamActiveCount(stream) == 1 || !devices.isEmpty()) { + if (outputDesc->getActivityCount(clientVolSrc) == 1 || !devices.isEmpty()) { // starting an output being rerouted? if (devices.isEmpty()) { devices = getNewOutputDevices(outputDesc, false /*fromCache*/); } - bool shouldWait = (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM)) || + bool shouldWait = + (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM)) || followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_NOTIFICATION)) || (beaconMuteLatency > 0)); - uint32_t waitMs = beaconMuteLatency; for (size_t i = 0; i < mOutputs.size(); i++) { sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i); if (desc != outputDesc) { + // An output has a shared device if + // - managed by the same hw module + // - supports the currently selected device + const bool sharedDevice = outputDesc->sharesHwModuleWith(desc) + && (!desc->filterSupportedDevices(devices).isEmpty()); + // force a device change if any other output is: // - managed by the same hw module - // - has a current device selection that differs from selected device. // - supports currently selected device + // - has a current device selection that differs from selected device. // - has an active audio patch // In this case, the audio HAL must receive the new device selection so that it can - // change the device currently selected by the other active output. - if (outputDesc->sharesHwModuleWith(desc) && + // change the device currently selected by the other output. + if (sharedDevice && desc->devices() != devices && - !(desc->filterSupportedDevices(devices).isEmpty()) && desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) { force = true; } // wait for audio on other active outputs to be presented when starting // a notification so that audio focus effect can propagate, or that a mute/unmute // event occurred for beacon - uint32_t latency = desc->latency(); - if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { - waitMs = latency; + const uint32_t latencyMs = desc->latency(); + const bool isActive = desc->isActive(latencyMs * 2); // account for drain + + if (shouldWait && isActive && (waitMs < latencyMs)) { + waitMs = latencyMs; } + + // Require mute check if another output is on a shared device + // and currently active to have proper drain and avoid pops. + // Note restoring AudioTracks onto this output needs to invoke + // a volume ramp if there is no mute. + requiresMuteCheck |= sharedDevice && isActive; } } - uint32_t muteWaitMs = setOutputDevices(outputDesc, devices, force, 0, NULL, address); + const uint32_t muteWaitMs = + setOutputDevices(outputDesc, devices, force, 0, NULL, requiresMuteCheck); // apply volume rules for current stream and device if necessary checkAndSetVolume(stream, - mVolumeCurves->getVolumeIndex(stream, outputDesc->devices().types()), + getVolumeCurves(stream).getVolumeIndex(outputDesc->devices().types()), outputDesc, outputDesc->devices().types()); @@ -1275,18 +1328,24 @@ status_t AudioPolicyManagerCustom::startSource(const sp<SwAudioOutputDescriptor> } } - return NO_ERROR; -} -void AudioPolicyManagerCustom::handleNotificationRoutingForStream(audio_stream_type_t stream) { - switch(stream) { - case AUDIO_STREAM_MUSIC: - checkOutputForAttributes(attributes_initializer(AUDIO_USAGE_NOTIFICATION)); - updateDevicesAndOutputs(); - break; - default: - break; + if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE && + mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { + setStrategyMute(streamToStrategy(AUDIO_STREAM_ALARM), true, outputDesc); } + + // Automatically enable the remote submix input when output is started on a re routing mix + // of type MIX_TYPE_RECORDERS + if (audio_is_remote_submix_device(devices.types()) && policyMix != NULL && + policyMix->mMixType == MIX_TYPE_RECORDERS) { + setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, + AUDIO_POLICY_DEVICE_STATE_AVAILABLE, + address, + "remote-submix", + AUDIO_FORMAT_DEFAULT); + } + + return NO_ERROR; } status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream, @@ -1301,9 +1360,8 @@ status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream, return INVALID_OPERATION; } // do not change actual stream volume if the stream is muted - if (outputDesc->mMuteCount[stream] != 0) { - ALOGVV("checkAndSetVolume() stream %d muted count %d", - stream, outputDesc->mMuteCount[stream]); + if (outputDesc->isMuted(streamToVolumeSource(stream))) { + ALOGVV("%s() stream %d muted count %d", __func__, stream, outputDesc->getMuteCount(stream)); return NO_ERROR; } audio_policy_forced_cfg_t forceUseForComm = @@ -1332,7 +1390,7 @@ status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream, 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)mVolumeCurves->getVolumeIndexMax(stream); + voiceVolume = (float)index/(float)getVolumeCurves(stream).getVolumeIndexMax(); } else { voiceVolume = 1.0; } @@ -1358,17 +1416,6 @@ status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream, return NO_ERROR; } -bool AudioPolicyManagerCustom::isDirectOutput(audio_io_handle_t output) { - for (size_t i = 0; i < mOutputs.size(); i++) { - audio_io_handle_t curOutput = mOutputs.keyAt(i); - sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i); - if ((curOutput == output) && (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { - return true; - } - } - return false; -} - bool static tryForDirectPCM(audio_output_flags_t flags) { bool trackDirectPCM = false; // Output request for track created by other apps @@ -1440,7 +1487,7 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( // compress should not be used for non-music streams ALOGE("Offloading only allowed with music stream"); return 0; - } + } if (mApmConfigs->isCompressVOIPEnabled()) { if (stream == AUDIO_STREAM_VOICE_CALL && @@ -1491,7 +1538,10 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( } } else { if (stream == AUDIO_STREAM_VOICE_CALL && - audio_is_linear_pcm(config->format)) { + audio_is_linear_pcm(config->format) && + (config->channel_mask == 1) && + (config->sample_rate == 8000 || config->sample_rate == 16000 || + config->sample_rate == 32000 || config->sample_rate == 48000)) { //check if VoIP output is not opened already bool voip_pcm_already_in_use = false; for (size_t i = 0; i < mOutputs.size(); i++) { @@ -1825,13 +1875,6 @@ audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices( } return AUDIO_IO_HANDLE_NONE; } - for (const std::pair<sp<TrackClientDescriptor>, size_t>& client_pair : mPrimaryOutput->getActiveClients()) { - if (client_pair.first->stream() == stream) { - outputDesc->changeStreamActiveCount(client_pair.first, -outputDesc->streamActiveCount(stream)); - break; - } - } - outputDesc->mStopTime[stream] = 0; outputDesc->mDirectOpenCount = 1; outputDesc->mDirectClientSession = session; @@ -1978,8 +2021,8 @@ uint32_t AudioPolicyManagerCustom::activeNonSoundTriggerInputsCountOnDevices(aud status_t AudioPolicyManagerCustom::startInput(audio_port_handle_t portId) { + ALOGV("%s portId %d", __FUNCTION__, portId); - ALOGV("startInput(portId:%d)", portId); sp<AudioInputDescriptor> inputDesc = mInputs.getInputForClient(portId); if (inputDesc == 0) { ALOGW("%s no input for client %d", __FUNCTION__, portId); @@ -1987,7 +2030,6 @@ status_t AudioPolicyManagerCustom::startInput(audio_port_handle_t portId) } audio_io_handle_t input = inputDesc->mIoHandle; - sp<RecordClientDescriptor> client = inputDesc->getClient(portId); if (client->active()) { ALOGW("%s input %d client %d already started", __FUNCTION__, input, client->portId()); @@ -2053,7 +2095,6 @@ status_t AudioPolicyManagerCustom::startInput(audio_port_handle_t portId) } status_t status = inputDesc->start(); if (status != NO_ERROR) { - inputDesc->setClientActive(client, false); return status; } @@ -2151,6 +2192,7 @@ status_t AudioPolicyManagerCustom::stopInput(audio_port_handle_t portId) } return status; } + AudioPolicyManagerCustom::AudioPolicyManagerCustom(AudioPolicyClientInterface *clientInterface) : AudioPolicyManager(clientInterface), mFallBackflag(AUDIO_OUTPUT_FLAG_NONE), diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h index 37fb806..34a6253 100644..100755 --- a/policy_hal/AudioPolicyManager.h +++ b/policy_hal/AudioPolicyManager.h @@ -128,8 +128,6 @@ protected: // Must be called before updateDevicesAndOutputs() void checkOutputForAttributes(const audio_attributes_t &attr); - // returns true if given output is direct output - bool isDirectOutput(audio_io_handle_t output); // if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force // the re-evaluation of the output device. @@ -146,16 +144,12 @@ protected: uint32_t setBeaconMute(bool){return 0;} static audio_output_flags_t getFallBackPath(); int mFallBackflag; - void moveGlobalEffect(); //parameter indicates of HDMI speakers disabled bool mHdmiAudioDisabled; //parameter indicates if HDMI plug in/out detected bool mHdmiAudioEvent; private: - // updates device caching and output for streams that can influence the - // routing of notifications - void handleNotificationRoutingForStream(audio_stream_type_t stream); // internal method to return the output handle for the given device and format audio_io_handle_t getOutputForDevices( const DeviceVector &devices, |