Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73890f65 authored by Eric Laurent's avatar Eric Laurent Committed by Automerger Merge Worker
Browse files

Merge changes I0817586a,I2799ac71,I6f9795e1 am: e49e56e3

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1575265

Change-Id: I8f4049033e324a4808e823cce53fa622ca881853
parents ba5ba39b e49e56e3
Loading
Loading
Loading
Loading
+18 −3
Original line number Original line Diff line number Diff line
@@ -158,7 +158,7 @@ public:
    virtual bool isDuplicated() const { return false; }
    virtual bool isDuplicated() const { return false; }
    virtual uint32_t latency() { return 0; }
    virtual uint32_t latency() { return 0; }
    virtual bool isFixedVolume(const DeviceTypeSet& deviceTypes);
    virtual bool isFixedVolume(const DeviceTypeSet& deviceTypes);
    virtual bool setVolume(float volumeDb,
    virtual bool setVolume(float volumeDb, bool muted,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           const DeviceTypeSet& deviceTypes,
                           const DeviceTypeSet& deviceTypes,
                           uint32_t delayMs,
                           uint32_t delayMs,
@@ -352,7 +352,22 @@ public:
            setClientActive(client, false);
            setClientActive(client, false);
        }
        }
    }
    }
    virtual bool setVolume(float volumeDb,

    /**
     * @brief setSwMute for SwOutput routed on a device that supports Hw Gain, this function allows
     * to mute the tracks associated to a given volume source only.
     * As an output may host one or more source(s), and as AudioPolicyManager may dispatch or not
     * the volume change request according to the priority of the volume source to control the
     * unique hw gain controller, a separated API allows to force a mute/unmute of a volume source.
     * @param muted true to mute, false otherwise
     * @param vs volume source to be considered
     * @param device scoped for the change
     * @param delayMs potentially applyed to prevent cut sounds.
     */
    void setSwMute(bool muted, VolumeSource vs, const StreamTypeVector &streams,
                   const DeviceTypeSet& device, uint32_t delayMs);

    virtual bool setVolume(float volumeDb, bool muted,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           const DeviceTypeSet& device,
                           const DeviceTypeSet& device,
                           uint32_t delayMs,
                           uint32_t delayMs,
@@ -437,7 +452,7 @@ public:


            void dump(String8 *dst) const override;
            void dump(String8 *dst) const override;


    virtual bool setVolume(float volumeDb,
    virtual bool setVolume(float volumeDb, bool muted,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           VolumeSource volumeSource, const StreamTypeVector &streams,
                           const DeviceTypeSet& deviceTypes,
                           const DeviceTypeSet& deviceTypes,
                           uint32_t delayMs,
                           uint32_t delayMs,
+37 −9
Original line number Original line Diff line number Diff line
@@ -155,7 +155,7 @@ bool AudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes __unu
    return false;
    return false;
}
}


bool AudioOutputDescriptor::setVolume(float volumeDb,
bool AudioOutputDescriptor::setVolume(float volumeDb, bool /*muted*/,
                                      VolumeSource volumeSource,
                                      VolumeSource volumeSource,
                                      const StreamTypeVector &/*streams*/,
                                      const StreamTypeVector &/*streams*/,
                                      const DeviceTypeSet& deviceTypes,
                                      const DeviceTypeSet& deviceTypes,
@@ -435,14 +435,36 @@ void SwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
}
}


bool SwAudioOutputDescriptor::setVolume(float volumeDb,
void SwAudioOutputDescriptor::setSwMute(
        bool muted, VolumeSource vs, const StreamTypeVector &streamTypes,
        const DeviceTypeSet& deviceTypes, uint32_t delayMs) {
    // volume source active and more than one volume source is active, otherwise, no-op or let
    // setVolume controlling SW and/or HW Gains
    if (!streamTypes.empty() && isActive(vs) && (getActiveVolumeSources().size() > 1)) {
        for (const auto& devicePort : devices()) {
            if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
                    devicePort->hasGainController(true /*canUseForVolume*/)) {
                float volumeAmpl = muted ? 0.0f : Volume::DbToAmpl(0);
                ALOGV("%s: output: %d, vs: %d, muted: %d, active vs count: %zu", __func__,
                      mIoHandle, vs, muted, getActiveVolumeSources().size());
                for (const auto &stream : streamTypes) {
                    mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
                }
                return;
            }
        }
    }
}

bool SwAudioOutputDescriptor::setVolume(float volumeDb, bool muted,
                                        VolumeSource vs, const StreamTypeVector &streamTypes,
                                        VolumeSource vs, const StreamTypeVector &streamTypes,
                                        const DeviceTypeSet& deviceTypes,
                                        const DeviceTypeSet& deviceTypes,
                                        uint32_t delayMs,
                                        uint32_t delayMs,
                                        bool force)
                                        bool force)
{
{
    StreamTypeVector streams = streamTypes;
    StreamTypeVector streams = streamTypes;
    if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, deviceTypes, delayMs, force)) {
    if (!AudioOutputDescriptor::setVolume(
            volumeDb, muted, vs, streamTypes, deviceTypes, delayMs, force)) {
        return false;
        return false;
    }
    }
    if (streams.empty()) {
    if (streams.empty()) {
@@ -459,11 +481,17 @@ bool SwAudioOutputDescriptor::setVolume(float volumeDb,
            // different Volume Source (or if we allow several curves within same volume group)
            // different Volume Source (or if we allow several curves within same volume group)
            //
            //
            // @todo: default stream volume to max (0) when using HW Port gain?
            // @todo: default stream volume to max (0) when using HW Port gain?
            float volumeAmpl = Volume::DbToAmpl(0);
            // Allows to set SW Gain on AudioFlinger if:
            //    -volume group has explicit stream(s) associated
            //    -volume group with no explicit stream(s) is the only active source on this output
            // Allows to mute SW Gain on AudioFlinger only for volume group with explicit stream(s)
            if (!streamTypes.empty() || (getActiveVolumeSources().size() == 1)) {
                const bool canMute = muted && (volumeDb != 0.0f) && !streamTypes.empty();
                float volumeAmpl = canMute ? 0.0f : Volume::DbToAmpl(0);
                for (const auto &stream : streams) {
                for (const auto &stream : streams) {
                    mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
                    mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
                }
                }

            }
            AudioGains gains = devicePort->getGains();
            AudioGains gains = devicePort->getGains();
            int gainMinValueInMb = gains[0]->getMinValueInMb();
            int gainMinValueInMb = gains[0]->getMinValueInMb();
            int gainMaxValueInMb = gains[0]->getMaxValueInMb();
            int gainMaxValueInMb = gains[0]->getMaxValueInMb();
@@ -698,14 +726,14 @@ void HwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
}
}




bool HwAudioOutputDescriptor::setVolume(float volumeDb,
bool HwAudioOutputDescriptor::setVolume(float volumeDb, bool muted,
                                        VolumeSource volumeSource, const StreamTypeVector &streams,
                                        VolumeSource volumeSource, const StreamTypeVector &streams,
                                        const DeviceTypeSet& deviceTypes,
                                        const DeviceTypeSet& deviceTypes,
                                        uint32_t delayMs,
                                        uint32_t delayMs,
                                        bool force)
                                        bool force)
{
{
    bool changed = AudioOutputDescriptor::setVolume(
    bool changed = AudioOutputDescriptor::setVolume(
            volumeDb, volumeSource, streams, deviceTypes, delayMs, force);
            volumeDb, muted, volumeSource, streams, deviceTypes, delayMs, force);


    if (changed) {
    if (changed) {
      // TODO: use gain controller on source device if any to adjust volume
      // TODO: use gain controller on source device if any to adjust volume
+56 −33
Original line number Original line Diff line number Diff line
@@ -1845,7 +1845,7 @@ status_t AudioPolicyManager::startSource(const sp<SwAudioOutputDescriptor>& outp
    if (stream == AUDIO_STREAM_TTS) {
    if (stream == AUDIO_STREAM_TTS) {
        ALOGV("\t found BEACON stream");
        ALOGV("\t found BEACON stream");
        if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(
        if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(
                                    toVolumeSource(AUDIO_STREAM_TTS) /*sourceToIgnore*/)) {
                                    toVolumeSource(AUDIO_STREAM_TTS, false) /*sourceToIgnore*/)) {
            return INVALID_OPERATION;
            return INVALID_OPERATION;
        } else {
        } else {
            beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
            beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
@@ -2067,12 +2067,20 @@ status_t AudioPolicyManager::stopSource(const sp<SwAudioOutputDescriptor>& outpu
        if (outputDesc->getActivityCount(clientVolSrc) == 0 || forceDeviceUpdate) {
        if (outputDesc->getActivityCount(clientVolSrc) == 0 || forceDeviceUpdate) {
            outputDesc->setStopTime(client, systemTime());
            outputDesc->setStopTime(client, systemTime());
            DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/);
            DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/);

            // If the routing does not change, if an output is routed on a device using HwGain
            // (aka setAudioPortConfig) and there are still active clients following different
            // volume group(s), force reapply volume
            bool requiresVolumeCheck = outputDesc->getActivityCount(clientVolSrc) == 0 &&
                    outputDesc->useHwGain() && outputDesc->isAnyActive(VOLUME_SOURCE_NONE);

            // delay the device switch by twice the latency because stopOutput() is executed when
            // delay the device switch by twice the latency because stopOutput() is executed when
            // the track stop() command is received and at that time the audio track buffer can
            // the track stop() command is received and at that time the audio track buffer can
            // still contain data that needs to be drained. The latency only covers the audio HAL
            // still contain data that needs to be drained. The latency only covers the audio HAL
            // and kernel buffers. Also the latency does not always include additional delay in the
            // and kernel buffers. Also the latency does not always include additional delay in the
            // audio path (audio DSP, CODEC ...)
            // audio path (audio DSP, CODEC ...)
            setOutputDevices(outputDesc, newDevices, false, outputDesc->latency()*2);
            setOutputDevices(outputDesc, newDevices, false, outputDesc->latency()*2,
                             nullptr, true /*requiresMuteCheck*/, requiresVolumeCheck);


            // force restoring the device selection on other active outputs if it differs from the
            // force restoring the device selection on other active outputs if it differs from the
            // one being selected for this output
            // one being selected for this output
@@ -2828,6 +2836,8 @@ status_t AudioPolicyManager::setVolumeIndexForAttributes(const audio_attributes_
        // HW Gain management, do not change the volume
        // HW Gain management, do not change the volume
        if (desc->useHwGain()) {
        if (desc->useHwGain()) {
            applyVolume = false;
            applyVolume = false;
            // If the volume source is active with higher priority source, ensure at least Sw Muted
            desc->setSwMute((index == 0), vs, curves.getStreamTypes(), curDevices, 0 /*delayMs*/);
            for (const auto &productStrategy : mEngine->getOrderedProductStrategies()) {
            for (const auto &productStrategy : mEngine->getOrderedProductStrategies()) {
                auto activeClients = desc->clientsList(true /*activeOnly*/, productStrategy,
                auto activeClients = desc->clientsList(true /*activeOnly*/, productStrategy,
                                                       false /*preferredDevice*/);
                                                       false /*preferredDevice*/);
@@ -2867,7 +2877,7 @@ status_t AudioPolicyManager::setVolumeIndexForAttributes(const audio_attributes_
        // handled by system UI
        // handled by system UI
        status_t volStatus = checkAndSetVolume(
        status_t volStatus = checkAndSetVolume(
                    curves, vs, index, desc, curDevices,
                    curves, vs, index, desc, curDevices,
                    ((vs == toVolumeSource(AUDIO_STREAM_SYSTEM))?
                    ((vs == toVolumeSource(AUDIO_STREAM_SYSTEM, false))?
                         TOUCH_SOUND_FIXED_DELAY_MS : 0));
                         TOUCH_SOUND_FIXED_DELAY_MS : 0));
        if (volStatus != NO_ERROR) {
        if (volStatus != NO_ERROR) {
            status = volStatus;
            status = volStatus;
@@ -3069,12 +3079,14 @@ status_t AudioPolicyManager::moveEffectsToIo(const std::vector<int>& ids, audio_


bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
{
{
    return mOutputs.isActive(toVolumeSource(stream), inPastMs);
    auto vs = toVolumeSource(stream, false);
    return vs != VOLUME_SOURCE_NONE ? mOutputs.isActive(vs, inPastMs) : false;
}
}


bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
{
{
    return mOutputs.isActiveRemotely(toVolumeSource(stream), inPastMs);
    auto vs = toVolumeSource(stream, false);
    return vs != VOLUME_SOURCE_NONE ? mOutputs.isActiveRemotely(vs, inPastMs) : false;
}
}


bool AudioPolicyManager::isSourceActive(audio_source_t source) const
bool AudioPolicyManager::isSourceActive(audio_source_t source) const
@@ -6095,7 +6107,7 @@ DeviceVector AudioPolicyManager::getNewOutputDevices(const sp<SwAudioOutputDescr


        auto doGetOutputDevicesForVoice = [&]() {
        auto doGetOutputDevicesForVoice = [&]() {
            return hasVoiceStream(streams) && (outputDesc == mPrimaryOutput ||
            return hasVoiceStream(streams) && (outputDesc == mPrimaryOutput ||
                outputDesc->isActive(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) &&
                outputDesc->isActive(toVolumeSource(AUDIO_STREAM_VOICE_CALL, false))) &&
                (isInCall() ||
                (isInCall() ||
                 mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc)) &&
                 mOutputs.isStrategyActiveOnSameModule(productStrategy, outputDesc)) &&
                !isStreamActive(AUDIO_STREAM_ENFORCED_AUDIBLE, 0);
                !isStreamActive(AUDIO_STREAM_ENFORCED_AUDIBLE, 0);
@@ -6191,7 +6203,7 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre
        devices.merge(curDevices);
        devices.merge(curDevices);
        for (audio_io_handle_t output : getOutputsForDevices(curDevices, mOutputs)) {
        for (audio_io_handle_t output : getOutputsForDevices(curDevices, mOutputs)) {
            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
            if (outputDesc->isActive(toVolumeSource(curStream))) {
            if (outputDesc->isActive(toVolumeSource(curStream, false))) {
                activeDevices.merge(outputDesc->devices());
                activeDevices.merge(outputDesc->devices());
            }
            }
        }
        }
@@ -6292,7 +6304,11 @@ uint32_t AudioPolicyManager::setBeaconMute(bool mute) {
        // mute/unmute AUDIO_STREAM_TTS on all outputs
        // mute/unmute AUDIO_STREAM_TTS on all outputs
        ALOGV("\t muting %d", mute);
        ALOGV("\t muting %d", mute);
        uint32_t maxLatency = 0;
        uint32_t maxLatency = 0;
        auto ttsVolumeSource = toVolumeSource(AUDIO_STREAM_TTS);
        auto ttsVolumeSource = toVolumeSource(AUDIO_STREAM_TTS, false);
        if (ttsVolumeSource == VOLUME_SOURCE_NONE) {
            ALOGV("\t no tts volume source available");
            return 0;
        }
        for (size_t i = 0; i < mOutputs.size(); i++) {
        for (size_t i = 0; i < mOutputs.size(); i++) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
            setVolumeSourceMute(ttsVolumeSource, mute/*on*/, desc, 0 /*delay*/, DeviceTypeSet());
            setVolumeSourceMute(ttsVolumeSource, mute/*on*/, desc, 0 /*delay*/, DeviceTypeSet());
@@ -6402,7 +6418,7 @@ uint32_t AudioPolicyManager::setOutputDevices(const sp<SwAudioOutputDescriptor>&
                                              bool force,
                                              bool force,
                                              int delayMs,
                                              int delayMs,
                                              audio_patch_handle_t *patchHandle,
                                              audio_patch_handle_t *patchHandle,
                                              bool requiresMuteCheck)
                                              bool requiresMuteCheck, bool requiresVolumeCheck)
{
{
    ALOGV("%s device %s delayMs %d", __func__, devices.toString().c_str(), delayMs);
    ALOGV("%s device %s delayMs %d", __func__, devices.toString().c_str(), delayMs);
    uint32_t muteWaitMs;
    uint32_t muteWaitMs;
@@ -6418,6 +6434,7 @@ uint32_t AudioPolicyManager::setOutputDevices(const sp<SwAudioOutputDescriptor>&
    // filter devices according to output selected
    // filter devices according to output selected
    DeviceVector filteredDevices = outputDesc->filterSupportedDevices(devices);
    DeviceVector filteredDevices = outputDesc->filterSupportedDevices(devices);
    DeviceVector prevDevices = outputDesc->devices();
    DeviceVector prevDevices = outputDesc->devices();
    DeviceVector availPrevDevices = mAvailableOutputDevices.filter(prevDevices);


    ALOGV("setOutputDevices() prevDevice %s", prevDevices.toString().c_str());
    ALOGV("setOutputDevices() prevDevice %s", prevDevices.toString().c_str());


@@ -6436,8 +6453,7 @@ uint32_t AudioPolicyManager::setOutputDevices(const sp<SwAudioOutputDescriptor>&
    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
    // output profile or if new device is not supported AND previous device(s) is(are) still
    // output profile or if new device is not supported AND previous device(s) is(are) still
    // available (otherwise reset device must be done on the output)
    // available (otherwise reset device must be done on the output)
    if (!devices.isEmpty() && filteredDevices.isEmpty() &&
    if (!devices.isEmpty() && filteredDevices.isEmpty() && !availPrevDevices.empty()) {
            !mAvailableOutputDevices.filter(prevDevices).empty()) {
        ALOGV("%s: unsupported device %s for output", __func__, devices.toString().c_str());
        ALOGV("%s: unsupported device %s for output", __func__, devices.toString().c_str());
        // restore previous device after evaluating strategy mute state
        // restore previous device after evaluating strategy mute state
        outputDesc->setDevices(prevDevices);
        outputDesc->setDevices(prevDevices);
@@ -6451,16 +6467,20 @@ uint32_t AudioPolicyManager::setOutputDevices(const sp<SwAudioOutputDescriptor>&
    //  AND the output is connected by a valid audio patch.
    //  AND the output is connected by a valid audio patch.
    // Doing this check here allows the caller to call setOutputDevices() without conditions
    // Doing this check here allows the caller to call setOutputDevices() without conditions
    if ((filteredDevices.isEmpty() || filteredDevices == prevDevices) &&
    if ((filteredDevices.isEmpty() || filteredDevices == prevDevices) &&
            !force && outputDesc->getPatchHandle() != 0) {
            !force && outputDesc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
        ALOGV("%s setting same device %s or null device, force=%d, patch handle=%d", __func__,
        ALOGV("%s setting same device %s or null device, force=%d, patch handle=%d", __func__,
              filteredDevices.toString().c_str(), force, outputDesc->getPatchHandle());
              filteredDevices.toString().c_str(), force, outputDesc->getPatchHandle());
        if (requiresVolumeCheck && !filteredDevices.isEmpty()) {
            ALOGV("%s setting same device on routed output, force apply volumes", __func__);
            applyStreamVolumes(outputDesc, filteredDevices.types(), delayMs, true /*force*/);
        }
        return muteWaitMs;
        return muteWaitMs;
    }
    }


    ALOGV("%s changing device to %s", __func__, filteredDevices.toString().c_str());
    ALOGV("%s changing device to %s", __func__, filteredDevices.toString().c_str());


    // do the routing
    // do the routing
    if (filteredDevices.isEmpty()) {
    if (filteredDevices.isEmpty() || mAvailableOutputDevices.filter(filteredDevices).empty()) {
        resetOutputDevice(outputDesc, delayMs, NULL);
        resetOutputDevice(outputDesc, delayMs, NULL);
    } else {
    } else {
        PatchBuilder patchBuilder;
        PatchBuilder patchBuilder;
@@ -6624,11 +6644,11 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves,
    // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
    // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
    // exploration of the dialer UI. In this situation, bring the accessibility volume closer to
    // exploration of the dialer UI. In this situation, bring the accessibility volume closer to
    // the ringtone volume
    // the ringtone volume
    const auto callVolumeSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL);
    const auto callVolumeSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL, false);
    const auto ringVolumeSrc = toVolumeSource(AUDIO_STREAM_RING);
    const auto ringVolumeSrc = toVolumeSource(AUDIO_STREAM_RING, false);
    const auto musicVolumeSrc = toVolumeSource(AUDIO_STREAM_MUSIC);
    const auto musicVolumeSrc = toVolumeSource(AUDIO_STREAM_MUSIC, false);
    const auto alarmVolumeSrc = toVolumeSource(AUDIO_STREAM_ALARM);
    const auto alarmVolumeSrc = toVolumeSource(AUDIO_STREAM_ALARM, false);
    const auto a11yVolumeSrc = toVolumeSource(AUDIO_STREAM_ACCESSIBILITY);
    const auto a11yVolumeSrc = toVolumeSource(AUDIO_STREAM_ACCESSIBILITY, false);


    if (volumeSource == a11yVolumeSrc
    if (volumeSource == a11yVolumeSrc
            && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState()) &&
            && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState()) &&
@@ -6641,12 +6661,12 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves,
    // in-call: always cap volume by voice volume + some low headroom
    // in-call: always cap volume by voice volume + some low headroom
    if ((volumeSource != callVolumeSrc && (isInCall() ||
    if ((volumeSource != callVolumeSrc && (isInCall() ||
                                           mOutputs.isActiveLocally(callVolumeSrc))) &&
                                           mOutputs.isActiveLocally(callVolumeSrc))) &&
            (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM) ||
            (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM, false) ||
             volumeSource == ringVolumeSrc || volumeSource == musicVolumeSrc ||
             volumeSource == ringVolumeSrc || volumeSource == musicVolumeSrc ||
             volumeSource == alarmVolumeSrc ||
             volumeSource == alarmVolumeSrc ||
             volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION) ||
             volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION, false) ||
             volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE) ||
             volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE, false) ||
             volumeSource == toVolumeSource(AUDIO_STREAM_DTMF) ||
             volumeSource == toVolumeSource(AUDIO_STREAM_DTMF, false) ||
             volumeSource == a11yVolumeSrc)) {
             volumeSource == a11yVolumeSrc)) {
        auto &voiceCurves = getVolumeCurves(callVolumeSrc);
        auto &voiceCurves = getVolumeCurves(callVolumeSrc);
        int voiceVolumeIndex = voiceCurves.getVolumeIndex(deviceTypes);
        int voiceVolumeIndex = voiceCurves.getVolumeIndex(deviceTypes);
@@ -6684,9 +6704,9 @@ float AudioPolicyManager::computeVolume(IVolumeCurves &curves,
             AUDIO_DEVICE_OUT_BLE_HEADSET}).empty() &&
             AUDIO_DEVICE_OUT_BLE_HEADSET}).empty() &&
            ((volumeSource == alarmVolumeSrc ||
            ((volumeSource == alarmVolumeSrc ||
              volumeSource == ringVolumeSrc) ||
              volumeSource == ringVolumeSrc) ||
             (volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION)) ||
             (volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION, false)) ||
             (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM)) ||
             (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM, false)) ||
             ((volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE)) &&
             ((volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE, false)) &&
              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
              (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
            curves.canBeMuted()) {
            curves.canBeMuted()) {


@@ -6772,10 +6792,10 @@ status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
               outputDesc->getMuteCount(volumeSource), outputDesc->isActive(volumeSource));
               outputDesc->getMuteCount(volumeSource), outputDesc->isActive(volumeSource));
        return NO_ERROR;
        return NO_ERROR;
    }
    }
    VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL);
    VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL, false);
    VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO);
    VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO, false);
    bool isVoiceVolSrc = callVolSrc == volumeSource;
    bool isVoiceVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (callVolSrc == volumeSource);
    bool isBtScoVolSrc = btScoVolSrc == volumeSource;
    bool isBtScoVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (btScoVolSrc == volumeSource);


    bool isScoRequested = isScoRequestedForComm();
    bool isScoRequested = isScoRequestedForComm();
    // do not change in call volume if bluetooth is connected and vice versa
    // do not change in call volume if bluetooth is connected and vice versa
@@ -6800,8 +6820,9 @@ status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
                    isSingleDeviceType(deviceTypes, audio_is_bluetooth_out_sco_device))) {
                    isSingleDeviceType(deviceTypes, audio_is_bluetooth_out_sco_device))) {
        volumeDb = 0.0f;
        volumeDb = 0.0f;
    }
    }
    const bool muted = (index == 0) && (volumeDb != 0.0f);
    outputDesc->setVolume(
    outputDesc->setVolume(
            volumeDb, volumeSource, curves.getStreamTypes(), deviceTypes, delayMs, force);
            volumeDb, muted, volumeSource, curves.getStreamTypes(), deviceTypes, delayMs, force);


    if (outputDesc == mPrimaryOutput && (isVoiceVolSrc || isBtScoVolSrc)) {
    if (outputDesc == mPrimaryOutput && (isVoiceVolSrc || isBtScoVolSrc)) {
        float voiceVolume;
        float voiceVolume;
@@ -6843,8 +6864,10 @@ void AudioPolicyManager::setStrategyMute(product_strategy_t strategy,
    for (auto attributes: mEngine->getAllAttributesForProductStrategy(strategy)) {
    for (auto attributes: mEngine->getAllAttributesForProductStrategy(strategy)) {
        ALOGVV("%s() attributes %s, mute %d, output ID %d", __func__,
        ALOGVV("%s() attributes %s, mute %d, output ID %d", __func__,
               toString(attributes).c_str(), on, outputDesc->getId());
               toString(attributes).c_str(), on, outputDesc->getId());
        VolumeSource source = toVolumeSource(attributes);
        VolumeSource source = toVolumeSource(attributes, false);
        if (std::find(begin(sourcesToMute), end(sourcesToMute), source) == end(sourcesToMute)) {
        if ((source != VOLUME_SOURCE_NONE) &&
                (std::find(begin(sourcesToMute), end(sourcesToMute), source)
                        == end(sourcesToMute))) {
            sourcesToMute.push_back(source);
            sourcesToMute.push_back(source);
        }
        }
    }
    }
@@ -6867,7 +6890,7 @@ void AudioPolicyManager::setVolumeSourceMute(VolumeSource volumeSource,
    if (on) {
    if (on) {
        if (!outputDesc->isMuted(volumeSource)) {
        if (!outputDesc->isMuted(volumeSource)) {
            if (curves.canBeMuted() &&
            if (curves.canBeMuted() &&
                    (volumeSource != toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE) ||
                    (volumeSource != toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE, false) ||
                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
                      AUDIO_POLICY_FORCE_NONE))) {
                      AUDIO_POLICY_FORCE_NONE))) {
                checkAndSetVolume(curves, volumeSource, 0, outputDesc, deviceTypes, delayMs);
                checkAndSetVolume(curves, volumeSource, 0, outputDesc, deviceTypes, delayMs);
+37 −7
Original line number Original line Diff line number Diff line
@@ -431,13 +431,30 @@ protected:
        {
        {
            return static_cast<VolumeSource>(volumeGroup);
            return static_cast<VolumeSource>(volumeGroup);
        }
        }
        VolumeSource toVolumeSource(const audio_attributes_t &attributes) const
        /**
         * @brief toVolumeSource converts an audio attributes into a volume source
         * (either a legacy stream or a volume group). If fallback on default is allowed, and if
         * the audio attributes do not follow any specific product strategy's rule, it will be
         * associated to default volume source, e.g. music. Thus, any of call of volume API
         * using this translation function may affect the default volume source.
         * If fallback is not allowed and no matching rule is identified for the given attributes,
         * the volume source will be undefined, thus, no volume will be altered/modified.
         * @param attributes to be considered
         * @param fallbackOnDefault
         * @return volume source associated with given attributes, otherwise either music if
         * fallbackOnDefault is set or none.
         */
        VolumeSource toVolumeSource(
            const audio_attributes_t &attributes, bool fallbackOnDefault = true) const
        {
        {
            return toVolumeSource(mEngine->getVolumeGroupForAttributes(attributes));
            return toVolumeSource(mEngine->getVolumeGroupForAttributes(
                attributes, fallbackOnDefault));
        }
        }
        VolumeSource toVolumeSource(audio_stream_type_t stream) const
        VolumeSource toVolumeSource(
            audio_stream_type_t stream, bool fallbackOnDefault = true) const
        {
        {
            return toVolumeSource(mEngine->getVolumeGroupForStreamType(stream));
            return toVolumeSource(mEngine->getVolumeGroupForStreamType(
                stream, fallbackOnDefault));
        }
        }
        IVolumeCurves &getVolumeCurves(VolumeSource volumeSource)
        IVolumeCurves &getVolumeCurves(VolumeSource volumeSource)
        {
        {
@@ -463,14 +480,27 @@ protected:
        void removeOutput(audio_io_handle_t output);
        void removeOutput(audio_io_handle_t output);
        void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
        void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);


        // change the route of the specified output. Returns the number of ms we have slept to
        /**
        // allow new routing to take effect in certain cases.
         * @brief setOutputDevices change the route of the specified output.
         * @param outputDesc to be considered
         * @param device to be considered to route the output
         * @param force if true, force the routing even if no change.
         * @param delayMs if specified, delay to apply for mute/volume op when changing device
         * @param patchHandle if specified, the patch handle this output is connected through.
         * @param requiresMuteCheck if specified, for e.g. when another output is on a shared device
         *        and currently active, allow to have proper drain and avoid pops
         * @param requiresVolumeCheck true if called requires to reapply volume if the routing did
         * not change (but the output is still routed).
         * @return the number of ms we have slept to allow new routing to take effect in certain
         * cases.
         */
        uint32_t setOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
        uint32_t setOutputDevices(const sp<SwAudioOutputDescriptor>& outputDesc,
                                  const DeviceVector &device,
                                  const DeviceVector &device,
                                  bool force = false,
                                  bool force = false,
                                  int delayMs = 0,
                                  int delayMs = 0,
                                  audio_patch_handle_t *patchHandle = NULL,
                                  audio_patch_handle_t *patchHandle = NULL,
                                  bool requiresMuteCheck = true);
                                  bool requiresMuteCheck = true,
                                  bool requiresVolumeCheck = false);
        status_t resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
        status_t resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
                                   int delayMs = 0,
                                   int delayMs = 0,
                                   audio_patch_handle_t *patchHandle = NULL);
                                   audio_patch_handle_t *patchHandle = NULL);