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

Commit 5baf07ca authored by Eric Laurent's avatar Eric Laurent Committed by Android Build Cherrypicker Worker
Browse files

audio policy: fix call volume with new call routing method

When audio HW audio sources are used for call routing, voice call volume
update to the audio HAL must also happen when a HW audio source is connected
for call RX path. This is because the primary output route does not necessary
match the actual call route anymore in which case the new requested volume
will not be applied.

Bug: 318050454
Test: repro steps in bug with audio AIDL HAL enabled and disabled.
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ae6e88cbc46f92e0ab24eaf6e226e1dd8f3cb63f)
Merged-In: I5918e4fd7a3d8b21af077067691dab431b89cd59
Change-Id: I5918e4fd7a3d8b21af077067691dab431b89cd59
parent c5f2ca78
Loading
Loading
Loading
Loading
+64 −28
Original line number Diff line number Diff line
@@ -3225,7 +3225,8 @@ status_t AudioPolicyManager::setVolumeIndexForAttributes(const audio_attributes_
        ALOGD("%s: no group matching with %s", __FUNCTION__, toString(attributes).c_str());
        return BAD_VALUE;
    }
    ALOGV("%s: group %d matching with %s", __FUNCTION__, group, toString(attributes).c_str());
    ALOGV("%s: group %d matching with %s index %d",
            __FUNCTION__, group, toString(attributes).c_str(), index);
    status_t status = NO_ERROR;
    IVolumeCurves &curves = getVolumeCurves(attributes);
    VolumeSource vs = toVolumeSource(group);
@@ -3342,6 +3343,21 @@ status_t AudioPolicyManager::setVolumeIndexForAttributes(const audio_attributes_
            status = volStatus;
        }
    }

    // update voice volume if the an active call route exists
    if (mCallRxSourceClient != nullptr && mCallRxSourceClient->isConnected()
            && (curSrcDevices.find(
                Volume::getDeviceForVolume({mCallRxSourceClient->sinkDevice()->type()}))
                != curSrcDevices.end())) {
        bool isVoiceVolSrc;
        bool isBtScoVolSrc;
        if (isVolumeConsistentForCalls(vs, {mCallRxSourceClient->sinkDevice()->type()},
                isVoiceVolSrc, isBtScoVolSrc, __func__)
                && (isVoiceVolSrc || isBtScoVolSrc)) {
            setVoiceVolume(index, curves, isVoiceVolSrc, 0);
        }
    }

    mpClientInterface->onAudioVolumeGroupChanged(group, 0 /*flags*/);
    return status;
}
@@ -7815,26 +7831,16 @@ status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
               outputDesc->getMuteCount(volumeSource), outputDesc->isActive(volumeSource));
        return NO_ERROR;
    }
    VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL, false);
    VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO, false);
    bool isVoiceVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (callVolSrc == volumeSource);
    bool isBtScoVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (btScoVolSrc == volumeSource);

    bool isScoRequested = isScoRequestedForComm();
    bool isHAUsed = isHearingAidUsedForComm();

    // do not change in call volume if bluetooth is connected and vice versa
    // if sco and call follow same curves, bypass forceUseForComm
    if ((callVolSrc != btScoVolSrc) &&
            ((isVoiceVolSrc && isScoRequested) ||
             (isBtScoVolSrc && !(isScoRequested || isHAUsed))) &&
            !isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
        ALOGV("%s cannot set volume group %d volume when is%srequested for comm", __func__,
             volumeSource, isScoRequested ? " " : " not ");
    bool isVoiceVolSrc;
    bool isBtScoVolSrc;
    if (!isVolumeConsistentForCalls(
            volumeSource, deviceTypes, isVoiceVolSrc, isBtScoVolSrc, __func__)) {
        // Do not return an error here as AudioService will always set both voice call
        // and bluetooth SCO volumes due to stream aliasing.
        // and Bluetooth SCO volumes due to stream aliasing.
        return NO_ERROR;
    }

    if (deviceTypes.empty()) {
        deviceTypes = outputDesc->devices().types();
        index = curves.getVolumeIndex(deviceTypes);
@@ -7859,8 +7865,16 @@ status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
            deviceTypes, delayMs, force, isVoiceVolSrc);

    if (outputDesc == mPrimaryOutput && (isVoiceVolSrc || isBtScoVolSrc)) {
        setVoiceVolume(index, curves, isVoiceVolSrc, delayMs);
    }
    return NO_ERROR;
}

void AudioPolicyManager::setVoiceVolume(
        int index, IVolumeCurves &curves, bool isVoiceVolSrc, int delayMs) {
    float voiceVolume;
        // Force voice volume to max or mute for Bluetooth SCO as other attenuations are managed by the headset
    // Force voice volume to max or mute for Bluetooth SCO as other attenuations are managed
    // by the headset
    if (isVoiceVolSrc) {
        voiceVolume = (float)index/(float)curves.getVolumeIndexMax();
    } else {
@@ -7871,7 +7885,29 @@ status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
        mLastVoiceVolume = voiceVolume;
    }
}
    return NO_ERROR;

bool AudioPolicyManager::isVolumeConsistentForCalls(VolumeSource volumeSource,
                                                   const DeviceTypeSet& deviceTypes,
                                                   bool& isVoiceVolSrc,
                                                   bool& isBtScoVolSrc,
                                                   const char* caller) {
    const VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL, false);
    const VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO, false);
    const bool isScoRequested = isScoRequestedForComm();
    const bool isHAUsed = isHearingAidUsedForComm();

    isVoiceVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (callVolSrc == volumeSource);
    isBtScoVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (btScoVolSrc == volumeSource);

    if ((callVolSrc != btScoVolSrc) &&
            ((isVoiceVolSrc && isScoRequested) ||
             (isBtScoVolSrc && !(isScoRequested || isHAUsed))) &&
            !isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
        ALOGV("%s cannot set volume group %d volume when is%srequested for comm", caller,
             volumeSource, isScoRequested ? " " : " not ");
        return false;
    }
    return true;
}

void AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
+14 −0
Original line number Diff line number Diff line
@@ -575,6 +575,20 @@ protected:
                                           DeviceTypeSet deviceTypes,
                                           int delayMs = 0, bool force = false);

        void setVoiceVolume(int index, IVolumeCurves &curves, bool isVoiceVolSrc, int delayMs);

        // returns true if the supplied set of volume source and devices are consistent with
        // call volume rules:
        // if Bluetooth SCO and voice call use different volume curves:
        // - do not apply voice call volume if Bluetooth SCO is used for call
        // - do not apply Bluetooth SCO volume if SCO or Hearing Aid is not used for call.
        // Also updates the booleans isVoiceVolSrc and isBtScoVolSrc according to the
        // volume source supplied.
        bool isVolumeConsistentForCalls(VolumeSource volumeSource,
                                       const DeviceTypeSet& deviceTypes,
                                       bool& isVoiceVolSrc,
                                       bool& isBtScoVolSrc,
                                       const char* caller);
        // apply all stream volumes to the specified output and device
        void applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
                                const DeviceTypeSet& deviceTypes,