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

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

Merge "[AudioPolicyManager] Voice Downlink Sink device selection" am: 0361312f am: 3e4db4ae

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I566642d11cdbe24ca4a7b778be15b5e4553304e2
parents a3c4ada7 3e4db4ae
Loading
Loading
Loading
Loading
+64 −39
Original line number Diff line number Diff line
@@ -257,11 +257,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
        } else {
            checkCloseOutputs();
        }

        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
            DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
            updateCallRouting(newDevices);
        }
        (void)updateCallRouting(false /*fromCache*/);
        const DeviceVector msdOutDevices = getMsdAudioOutDevices();
        for (size_t i = 0; i < mOutputs.size(); i++) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
@@ -349,10 +345,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
        // getDeviceForStrategy() cache
        updateDevicesAndOutputs();

        if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
            DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
            updateCallRouting(newDevices);
        }
        (void)updateCallRouting(false /*fromCache*/);
        // Reconnect Audio Source
        for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
            auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
@@ -517,23 +510,58 @@ status_t AudioPolicyManager::getHwOffloadEncodingFormatsSupportedForA2DP(
    return status;
}

uint32_t AudioPolicyManager::updateCallRouting(const DeviceVector &rxDevices, uint32_t delayMs)
DeviceVector AudioPolicyManager::selectBestRxSinkDevicesForCall(bool fromCache)
{
    DeviceVector rxSinkdevices{};
    rxSinkdevices = mEngine->getOutputDevicesForAttributes(
                attributes_initializer(AUDIO_USAGE_VOICE_COMMUNICATION), nullptr, fromCache);
    if (!rxSinkdevices.isEmpty() && mAvailableOutputDevices.contains(rxSinkdevices.itemAt(0))) {
        auto rxSinkDevice = rxSinkdevices.itemAt(0);
        auto telephonyRxModule = mHwModules.getModuleForDeviceType(
                    AUDIO_DEVICE_IN_TELEPHONY_RX, AUDIO_FORMAT_DEFAULT);
        // retrieve Rx Source device descriptor
        sp<DeviceDescriptor> rxSourceDevice = mAvailableInputDevices.getDevice(
                    AUDIO_DEVICE_IN_TELEPHONY_RX, String8(), AUDIO_FORMAT_DEFAULT);

        // RX Telephony and Rx sink devices are declared by Primary Audio HAL
        if (isPrimaryModule(telephonyRxModule) && (telephonyRxModule->getHalVersionMajor() >= 3) &&
                telephonyRxModule->supportsPatch(rxSourceDevice, rxSinkDevice)) {
            ALOGW("%s() device %s using HW Bridge", __func__, rxSinkDevice->toString().c_str());
            return DeviceVector(rxSinkDevice);
        }
    }
    // Note that despite the fact that getNewOutputDevices() is called on the primary output,
    // the device returned is not necessarily reachable via this output
    // (filter later by setOutputDevices())
    return getNewOutputDevices(mPrimaryOutput, fromCache);
}

status_t AudioPolicyManager::updateCallRouting(bool fromCache, uint32_t delayMs, uint32_t *waitMs)
{
    if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
        DeviceVector rxDevices = selectBestRxSinkDevicesForCall(fromCache);
        return updateCallRoutingInternal(rxDevices, delayMs, waitMs);
    }
    return INVALID_OPERATION;
}

status_t AudioPolicyManager::updateCallRoutingInternal(
        const DeviceVector &rxDevices, uint32_t delayMs, uint32_t *waitMs)
{
    bool createTxPatch = false;
    bool createRxPatch = false;
    uint32_t muteWaitMs = 0;

    if(!hasPrimaryOutput() ||
            mPrimaryOutput->devices().onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_STUB)) {
        return muteWaitMs;
        return INVALID_OPERATION;
    }
    ALOG_ASSERT(!rxDevices.isEmpty(), "updateCallRouting() no selected output device");
    ALOG_ASSERT(!rxDevices.isEmpty(), "%s() no selected output device", __func__);

    audio_attributes_t attr = { .source = AUDIO_SOURCE_VOICE_COMMUNICATION };
    auto txSourceDevice = mEngine->getInputDeviceForAttributes(attr);
    ALOG_ASSERT(txSourceDevice != 0, "updateCallRouting() input selected device not available");
    ALOG_ASSERT(txSourceDevice != 0, "%s() input selected device not available", __func__);

    ALOGV("updateCallRouting device rxDevice %s txDevice %s",
    ALOGV("%s device rxDevice %s txDevice %s", __func__,
          rxDevices.itemAt(0)->toString().c_str(), txSourceDevice->toString().c_str());

    disconnectTelephonyRxAudioSource();
@@ -562,8 +590,8 @@ uint32_t AudioPolicyManager::updateCallRouting(const DeviceVector &rxDevices, ui
            (telephonyRxModule->getHalVersionMajor() >= 3)) {
        if (rxSourceDevice == 0 || txSinkDevice == 0) {
            // RX / TX Telephony device(s) is(are) not currently available
            ALOGE("updateCallRouting() no telephony Tx and/or RX device");
            return muteWaitMs;
            ALOGE("%s() no telephony Tx and/or RX device", __func__);
            return INVALID_OPERATION;
        }
        // createAudioPatchInternal now supports both HW / SW bridging
        createRxPatch = true;
@@ -601,8 +629,10 @@ uint32_t AudioPolicyManager::updateCallRouting(const DeviceVector &rxDevices, ui
        }
        mCallTxPatch = createTelephonyPatch(false /*isRx*/, txSourceDevice, delayMs);
    }

    return muteWaitMs;
    if (waitMs != nullptr) {
        *waitMs = muteWaitMs;
    }
    return NO_ERROR;
}

sp<AudioPatch> AudioPolicyManager::createTelephonyPatch(
@@ -720,25 +750,22 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
    }

    if (hasPrimaryOutput()) {
        // Note that despite the fact that getNewOutputDevices() is called on the primary output,
        // the device returned is not necessarily reachable via this output
        if (state == AUDIO_MODE_IN_CALL) {
            (void)updateCallRouting(false /*fromCache*/, delayMs);
        } else {
            DeviceVector rxDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
            // force routing command to audio hardware when ending call
            // even if no device change is needed
            if (isStateInCall(oldState) && rxDevices.isEmpty()) {
                rxDevices = mPrimaryOutput->devices();
            }

        if (state == AUDIO_MODE_IN_CALL) {
            updateCallRouting(rxDevices, delayMs);
        } else if (oldState == AUDIO_MODE_IN_CALL) {
            if (oldState == AUDIO_MODE_IN_CALL) {
                disconnectTelephonyRxAudioSource();
                if (mCallTxPatch != 0) {
                    releaseAudioPatchInternal(mCallTxPatch->getHandle());
                    mCallTxPatch.clear();
                }
            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
        } else {
            }
            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
        }
    }
@@ -3236,9 +3263,7 @@ status_t AudioPolicyManager::setDevicesRoleForStrategy(product_strategy_t strate
void AudioPolicyManager::updateCallAndOutputRouting(bool forceVolumeReeval, uint32_t delayMs)
{
    uint32_t waitMs = 0;
    if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
        DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/);
        waitMs = updateCallRouting(newDevices, delayMs);
    if (updateCallRouting(true /*fromCache*/, delayMs, &waitMs) == NO_ERROR) {
        // Only apply special touch sound delay once
        delayMs = 0;
    }
+14 −1
Original line number Diff line number Diff line
@@ -729,9 +729,22 @@ protected:
                    String8(devices.itemAt(0)->address().c_str()) : String8("");
        }

        uint32_t updateCallRouting(const DeviceVector &rxDevices, uint32_t delayMs = 0);
        status_t updateCallRouting(
                bool fromCache, uint32_t delayMs = 0, uint32_t *waitMs = nullptr);
        status_t updateCallRoutingInternal(
                const DeviceVector &rxDevices, uint32_t delayMs, uint32_t *waitMs);
        sp<AudioPatch> createTelephonyPatch(bool isRx, const sp<DeviceDescriptor> &device,
                                            uint32_t delayMs);
        /**
         * @brief selectBestRxSinkDevicesForCall: if the primary module host both Telephony Rx/Tx
         * devices, and it declares also supporting a HW bridge between the Telephony Rx and the
         * given sink device for Voice Call audio attributes, select this device in prio.
         * Otherwise, getNewOutputDevices() is called on the primary output to select sink device.
         * @param fromCache true to prevent engine reconsidering all product strategies and retrieve
         * from engine cache.
         * @return vector of devices, empty if none is found.
         */
        DeviceVector selectBestRxSinkDevicesForCall(bool fromCache);
        bool isDeviceOfModule(const sp<DeviceDescriptor>& devDesc, const char *moduleId) const;

        status_t startSource(const sp<SwAudioOutputDescriptor>& outputDesc,