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

Commit 15b40177 authored by Jeremy Wu's avatar Jeremy Wu
Browse files

Reapply "APM: use routing checks with ioprofile"

This reverts commit dc1aa1bb,
and adds the change to enhance flag checking.

In the original CL, when the flag is disabled,
|getAudioMixPort| will return |BAD_VALUE| if the IO handle is none.

That makes some routable checks end up in false, and break CUJs.

This CL adds the flag check when such checks are involved, so that
the legacy logic is truly guarded.

Bug: 367117623
Test: Verify BT audio works on incoming call w&w/o flag on Caiman
Flag: com.android.media.audioserver.enable_strict_port_routing_checks

Change-Id: If3b439f842e0c47bcf19fceab8f5d7829271576e
parent d4c8ff09
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ public:
                        ((mFlags.input & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0)));
    }

    void setHalIdForTest(int32_t halId) { mHalId = halId; }
    int32_t getHalId() const { return mHalId; }

    void dump(std::string *dst, int spaces,
+105 −66
Original line number Diff line number Diff line
@@ -204,11 +204,15 @@ void AudioPolicyManager::addRoutableDeviceToProfiles(const sp<DeviceDescriptor>
            struct audio_port_v7 mixPort{};
            profile->toAudioPort(&mixPort);

            bool isRoutable = profile->supportsDevice(device) &&
            bool isSupported = profile->supportsDevice(device);

            // When flag is disabled, routable should be equivalent to supported.
            bool isRoutable =
                !com::android::media::audioserver::enable_strict_port_routing_checks() ||
                mpClientInterface->getAudioMixPort(&devicePort, &mixPort,
                                                   profile->getHalId()) == OK;

            if (isRoutable) {
            if (isSupported && isRoutable) {
                profile->addRoutableDevice(device);
            }
        }
@@ -395,7 +399,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
                }
                if (!desc->isDuplicated() && desc->mProfile->hasDynamicAudioProfile() &&
                        !activeMediaDevices.empty() && desc->devices() != activeMediaDevices &&
                        desc->supportsDevicesForPlayback(activeMediaDevices)) {
                        desc->routesToDevicesForPlayback(activeMediaDevices)) {
                    // Reopen the output to query the dynamic profiles when there is not active
                    // clients or all active clients will be rerouted. Otherwise, set the flag
                    // `mPendingReopenToQueryProfiles` in the SwOutputDescriptor so that the output
@@ -406,7 +410,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
                        desc->mPendingReopenToQueryProfiles = true;
                    }
                }
                if (!desc->supportsDevicesForPlayback(activeMediaDevices)) {
                if (!desc->routesToDevicesForPlayback(activeMediaDevices)) {
                    // Clear the flag that previously set for re-querying profiles.
                    desc->mPendingReopenToQueryProfiles = false;
                }
@@ -443,7 +447,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
                return NO_MEMORY;
            }

            // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
            // Before checking inputs, broadcast connect event to allow HAL to retrieve dynamic
            // parameters on newly connected devices (instead of opening the inputs...)
            if (broadcastDeviceConnectionState(
                        device, media::DeviceConnectedState::CONNECTED) != NO_ERROR) {
@@ -453,6 +457,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescript
                      device->toString().c_str(), device->getEncodedFormat());
                return INVALID_OPERATION;
            }

            // Propagate device availability to Engine
            setEngineDeviceConnectionState(device, state);

@@ -1184,7 +1189,7 @@ sp<IOProfile> AudioPolicyManager::searchCompatibleProfileHwModules (
                 continue;
             }
             // reject profiles not corresponding to a device currently available
             if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) {
             if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getRoutableDevices())) {
                 continue;
             }
             // reject profiles if connected device does not support codec
@@ -1222,11 +1227,11 @@ sp<IOProfile> AudioPolicyManager::getSpatializerOutputProfile(
            }
            if (!devices.empty()) {
                // reject profiles not corresponding to a device currently available
                DeviceVector supportedDevices = curProfile->getSupportedDevices();
                if (!mAvailableOutputDevices.containsAtLeastOne(supportedDevices)) {
                DeviceVector routableDevices = curProfile->getRoutableDevices();
                if (!mAvailableOutputDevices.containsAtLeastOne(routableDevices)) {
                    continue;
                }
                if (supportedDevices.getDevicesFromDeviceTypeAddrVec(devices).size()
                if (routableDevices.getDevicesFromDeviceTypeAddrVec(devices).size()
                        != devices.size()) {
                    continue;
                }
@@ -2003,13 +2008,13 @@ status_t AudioPolicyManager::getMsdProfiles(bool hwAvSync,
    }
    for (const auto &inProfile : inputProfiles) {
        if (hwAvSync == ((inProfile->getFlags() & AUDIO_INPUT_FLAG_HW_AV_SYNC) != 0) &&
                inProfile->supportsDevice(sourceDevice)) {
                inProfile->routesToDevice(sourceDevice)) {
            appendAudioProfiles(sourceProfiles, inProfile->getAudioProfiles());
        }
    }
    for (const auto &outProfile : outputProfiles) {
        if (hwAvSync == ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) &&
                outProfile->supportsDevice(sinkDevice)) {
                outProfile->routesToDevice(sinkDevice)) {
            appendAudioProfiles(sinkProfiles, outProfile->getAudioProfiles());
        }
    }
@@ -2644,7 +2649,7 @@ status_t AudioPolicyManager::startSource(const sp<SwAudioOutputDescriptor>& outp
                // - managed by the same hw module
                // - supports the currently selected device
                const bool sharedDevice = outputDesc->sharesHwModuleWith(desc)
                        && (!desc->filterSupportedDevices(devices).isEmpty());
                        && (!desc->filterRoutableDevices(devices).isEmpty());

                // force a device change if any other output is:
                // - managed by the same hw module
@@ -3627,7 +3632,7 @@ void AudioPolicyManager::closeClient(audio_port_handle_t portId)

bool AudioPolicyManager::checkCloseInput(const sp<AudioInputDescriptor>& input) {
    if (input->clientsList().size() == 0
            || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())) {
            || !mAvailableInputDevices.containsAtLeastOne(input->routableDevices())) {
        return true;
    }
    for (const auto& client : input->clientsList()) {
@@ -3635,7 +3640,7 @@ bool AudioPolicyManager::checkCloseInput(const sp<AudioInputDescriptor>& input)
            mEngine->getInputDeviceForAttributes(
                    client->attributes(), false /*ignorePreferredDevice*/, client->uid(),
                    client->session());
        if (!input->supportedDevices().contains(device)) {
        if (!input->routableDevices().contains(device)) {
            return true;
        }
    }
@@ -4512,7 +4517,7 @@ std::vector<sp<SwAudioOutputDescriptor>> AudioPolicyManager::getSoftwareOutputsF
        deviceDescriptors.add(desc);
    }
    for (size_t i = 0; i < mOutputs.size(); i++) {
        if (!mOutputs.valueAt(i)->supportsAtLeastOne(deviceDescriptors)) {
        if (!mOutputs.valueAt(i)->routesToAtLeastOne(deviceDescriptors)) {
            continue;
        }
        outputs.push_back(mOutputs.valueAt(i));
@@ -4638,7 +4643,7 @@ void AudioPolicyManager::updateInputRouting() {
        }
        auto newDevice = getNewInputDevice(activeDesc);
        // Force new input selection if the new device can not be reached via current input
        if (activeDesc->mProfile->getSupportedDevices().contains(newDevice)) {
        if (activeDesc->mProfile->getRoutableDevices().contains(newDevice)) {
            setInputDevice(activeDesc->mIoHandle, newDevice);
        } else {
            closeInput(activeDesc->mIoHandle);
@@ -5109,7 +5114,7 @@ audio_direct_mode_t AudioPolicyManager::getDirectPlaybackSupport(const audio_att
                continue;
            }
            // reject profiles not corresponding to a device currently available
            if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) {
            if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getRoutableDevices())) {
                continue;
            }
            if (offloadPossible && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
@@ -5169,7 +5174,7 @@ status_t AudioPolicyManager::getSupportedMixerAttributes(
    }
    for (const auto& hwModule : mHwModules) {
        for (const auto& curProfile : hwModule->getOutputProfiles()) {
            if (curProfile->supportsDevice(deviceDescriptor)) {
            if (curProfile->routesToDevice(deviceDescriptor)) {
                curProfile->toSupportedMixerAttributes(&mixerAttrs);
            }
        }
@@ -5210,7 +5215,9 @@ status_t AudioPolicyManager::setPreferredMixerAttributes(
    DeviceVector devices(deviceDescriptor);
    for (const auto& hwModule : mHwModules) {
        for (const auto& curProfile : hwModule->getOutputProfiles()) {
            if (curProfile->hasDynamicAudioProfile()
            if ((!com::android::media::audioserver::enable_strict_port_routing_checks()
                      || curProfile->routesToDevice(deviceDescriptor))
                    && curProfile->hasDynamicAudioProfile()
                    && curProfile->getCompatibilityScore(
                            devices,
                            mixerAttributes->config.sample_rate,
@@ -6721,13 +6728,13 @@ bool AudioPolicyManager::isOutputOnlyAvailableRouteToSomeDevice(
    if (outputDesc->isDuplicated()) {
        return false;
    }
    DeviceVector devices = outputDesc->supportedDevices();
    DeviceVector devices = outputDesc->routableDevices();
    for (size_t i = 0; i < mOutputs.size(); i++) {
        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
        if (desc == outputDesc || desc->isDuplicated()) {
            continue;
        }
        DeviceVector sharedDevices = desc->filterSupportedDevices(devices);
        DeviceVector sharedDevices = desc->filterRoutableDevices(devices);
        if (!sharedDevices.isEmpty()
                && (desc->devicesSupportEncodedFormats(sharedDevices.types())
                    == outputDesc->devicesSupportEncodedFormats(sharedDevices.types()))) {
@@ -6958,7 +6965,7 @@ void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
                      outProfile->maxOpenCount, outProfile->getTagName().c_str());
                continue;
            }
            if (!outProfile->hasSupportedDevices()) {
            if (!outProfile->hasRoutableDevices()) {
                ALOGW("Output profile contains no device on module %s", hwModule->getName());
                continue;
            }
@@ -6967,20 +6974,20 @@ void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
                mTtsOutputAvailable = true;
            }

            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
            DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getOutputDevices());
            sp<DeviceDescriptor> supportedDevice = 0;
            if (supportedDevices.contains(mConfig->getDefaultOutputDevice())) {
                supportedDevice = mConfig->getDefaultOutputDevice();
            const DeviceVector &routableDevices = outProfile->getRoutableDevices();
            DeviceVector availProfileDevices = routableDevices.filter(mConfig->getOutputDevices());
            sp<DeviceDescriptor> routableDevice = 0;
            if (routableDevices.contains(mConfig->getDefaultOutputDevice())) {
                routableDevice = mConfig->getDefaultOutputDevice();
            } else {
                // choose first device present in profile's SupportedDevices also part of
                // choose first device present in profile's RoutableDevices also part of
                // mAvailableOutputDevices.
                if (availProfileDevices.isEmpty()) {
                    continue;
                }
                supportedDevice = availProfileDevices.itemAt(0);
                routableDevice = availProfileDevices.itemAt(0);
            }
            if (!mConfig->getOutputDevices().contains(supportedDevice)) {
            if (!mConfig->getOutputDevices().contains(routableDevice)) {
                continue;
            }

@@ -6997,12 +7004,12 @@ void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
            audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
            status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
                                               DeviceVector(supportedDevice),
                                               DeviceVector(routableDevice),
                                               AUDIO_STREAM_DEFAULT,
                                               &flags, &output, attributes);
            if (status != NO_ERROR) {
                ALOGW("Cannot open output stream for devices %s on hw module %s",
                      supportedDevice->toString().c_str(), hwModule->getName());
                      routableDevice->toString().c_str(), hwModule->getName());
                continue;
            }
            for (const auto &device : availProfileDevices) {
@@ -7025,7 +7032,7 @@ void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
            } else {
                addOutput(output, outputDesc);
                setOutputDevices(__func__, outputDesc,
                                 DeviceVector(supportedDevice),
                                 DeviceVector(routableDevice),
                                 true,
                                 0,
                                 NULL);
@@ -7039,14 +7046,14 @@ void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
                      inProfile->maxOpenCount, inProfile->getTagName().c_str());
                continue;
            }
            if (!inProfile->hasSupportedDevices()) {
            if (!inProfile->hasRoutableDevices()) {
                ALOGW("Input profile contains no device on module %s", hwModule->getName());
                continue;
            }
            // chose first device present in profile's SupportedDevices also part of
            // chose first device present in profile's RoutableDevices also part of
            // available input devices
            const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
            DeviceVector availProfileDevices = supportedDevices.filter(mConfig->getInputDevices());
            const DeviceVector &routableDevices = inProfile->getRoutableDevices();
            DeviceVector availProfileDevices = routableDevices.filter(mConfig->getInputDevices());
            if (availProfileDevices.isEmpty()) {
                ALOGV("%s: Input device list is empty! for profile %s",
                    __func__, inProfile->getTagName().c_str());
@@ -7166,7 +7173,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
        // then list already open outputs that can be routed to this device
        for (size_t i = 0; i < mOutputs.size(); i++) {
            desc = mOutputs.valueAt(i);
            if (!desc->isDuplicated() && desc->supportsDevice(device)
            if (!desc->isDuplicated() && desc->routesToDevice(device)
                    && desc->devicesSupportEncodedFormats({deviceType})) {
                ALOGV("checkOutputsForDevice(): adding opened output %d on device %s",
                      mOutputs.keyAt(i), device->toString().c_str());
@@ -7178,7 +7185,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
        for (const auto& hwModule : mHwModules) {
            for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
                sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
                if (profile->supportsDevice(device)) {
                if (profile->routesToDevice(device)) {
                    profiles.add(profile);
                    ALOGV("%s(): adding profile %s from module %s",
                            __func__, profile->getTagName().c_str(), hwModule->getName());
@@ -7262,10 +7269,10 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
            desc = mOutputs.valueAt(i);
            if (!desc->isDuplicated()) {
                // exact match on device
                if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)
                if (device_distinguishes_on_address(deviceType) && desc->routesToDevice(device)
                        && desc->containsSingleDeviceSupportingEncodedFormats(device)) {
                    outputs.add(mOutputs.keyAt(i));
                } else if (!mAvailableOutputDevices.containsAtLeastOne(desc->supportedDevices())) {
                } else if (!mAvailableOutputDevices.containsAtLeastOne(desc->routableDevices())) {
                    ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
                            mOutputs.keyAt(i));
                    outputs.add(mOutputs.keyAt(i));
@@ -7276,7 +7283,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
        for (const auto& hwModule : mHwModules) {
            for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
                sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
                if (!profile->supportsDevice(device)) {
                if (!profile->routesToDevice(device)) {
                    continue;
                }
                ALOGV("%s(): clearing direct output profile %s on module %s",
@@ -7286,18 +7293,18 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
                    continue;
                }
                // When a device is disconnected, if there is an IOProfile that contains dynamic
                // profiles and supports the disconnected device, call getAudioPort to repopulate
                // the capabilities of the devices that is supported by the IOProfile.
                for (const auto& supportedDevice : profile->getSupportedDevices()) {
                    if (supportedDevice == device ||
                            !mAvailableOutputDevices.contains(supportedDevice)) {
                // profiles and routes to the disconnected device, call getAudioPort to repopulate
                // the capabilities of the devices that is routable from/to the IOProfile.
                for (const auto& routableDevice : profile->getRoutableDevices()) {
                    if (routableDevice == device ||
                            !mAvailableOutputDevices.contains(routableDevice)) {
                        continue;
                    }
                    struct audio_port_v7 port;
                    supportedDevice->toAudioPort(&port);
                    routableDevice->toAudioPort(&port);
                    status_t status = mpClientInterface->getAudioPort(&port);
                    if (status == NO_ERROR) {
                        supportedDevice->importAudioPort(port);
                        routableDevice->importAudioPort(port);
                    }
                }
            }
@@ -7333,7 +7340,7 @@ status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& de
                 profile_index++) {
                sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];

                if (profile->supportsDevice(device)) {
                if (profile->routesToDevice(device)) {
                    profiles.add(profile);
                    ALOGV("%s : adding profile %s from module %s", __func__,
                          profile->getTagName().c_str(), hwModule->getName());
@@ -7437,7 +7444,7 @@ status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& de
                 profile_index < hwModule->getInputProfiles().size();
                 profile_index++) {
                sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];
                if (profile->supportsDevice(device)) {
                if (profile->routesToDevice(device)) {
                    ALOGV("%s: clearing direct input profile %s on module %s", __func__,
                            profile->getTagName().c_str(), hwModule->getName());
                    profile->clearAudioProfiles();
@@ -7585,8 +7592,8 @@ SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevices(
    for (size_t i = 0; i < openOutputs.size(); i++) {
        ALOGVV("output %zu isDuplicated=%d device=%s",
                i, openOutputs.valueAt(i)->isDuplicated(),
                openOutputs.valueAt(i)->supportedDevices().toString().c_str());
        if (openOutputs.valueAt(i)->supportsAllDevices(devices)
                openOutputs.valueAt(i)->routableDevices().toString().c_str());
        if (openOutputs.valueAt(i)->routesToAllDevices(devices)
                && openOutputs.valueAt(i)->devicesSupportEncodedFormats(devices.types())) {
            ALOGVV("%s() found output %d", __func__, openOutputs.keyAt(i));
            outputs.add(openOutputs.keyAt(i));
@@ -7668,7 +7675,7 @@ void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr
    std::vector<sp<SwAudioOutputDescriptor>> invalidatedOutputs;
    // take into account dynamic audio policies related changes: if a client is now associated
    // to a different policy mix than at creation time, invalidate corresponding stream
    // invalidate clients on outputs that do not support all the newly selected devices for the
    // invalidate clients on outputs that do not route to all the newly selected devices for the
    // strategy
    for (size_t i = 0; i < mPreviousOutputs.size(); i++) {
        const sp<SwAudioOutputDescriptor>& desc = mPreviousOutputs.valueAt(i);
@@ -7681,7 +7688,7 @@ void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr
                    || client->isInvalid()) {
                continue;
            }
            if (!desc->supportsAllDevices(newDevices)) {
            if (!desc->routesToAllDevices(newDevices)) {
                invalidatedOutputs.push_back(desc);
                break;
            }
@@ -7985,6 +7992,25 @@ DeviceVector AudioPolicyManager::getNewOutputDevices(const sp<SwAudioOutputDescr
            // check the route (would force modifying configuration file for this profile)
            auto attr = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
            devices = mEngine->getOutputDevicesForAttributes(attr, nullptr, fromCache);

            if (devices.empty()) {
                ALOGW("%s: no device were retrieved for specified attributes", __func__);
            }

            if (com::android::media::audioserver::enable_strict_port_routing_checks()) {
                // Filter out devices that are indicated by the HAL as non-routable.
                auto routableDevices = devices.filter([&](auto device) {
                      return outputDesc->mProfile->routesToDevice(device); });

                if (routableDevices.empty()) {
                    ALOGW("%s: no device in %s are routable for profile %s", __func__,
                          routableDevices.toString().c_str(),
                          outputDesc->mProfile->getTagName().c_str());
                }

                devices = routableDevices;
            }

            break;
        }
    }
@@ -8040,6 +8066,14 @@ sp<DeviceDescriptor> AudioPolicyManager::getNewInputDevice(
                attributes, false /*ignorePreferredDevice*/, uid, session);
    }

    if (com::android::media::audioserver::enable_strict_port_routing_checks() &&
          !inputDesc->mProfile->routesToDevice(device)) {
        ALOGW("%s: profile %s is not routable to device %s", __func__,
              inputDesc->mProfile->getTagName().c_str(),
              inputDesc->getDevice()->toString().c_str());
        return nullptr;
    }

    return device;
}

@@ -8164,7 +8198,7 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescr
        auto attributes = mEngine->getAllAttributesForProductStrategy(productStrategy).front();
        DeviceVector curDevices =
                mEngine->getOutputDevicesForAttributes(attributes, nullptr, false/*fromCache*/);
        curDevices = curDevices.filter(outputDesc->supportedDevices());
        curDevices = curDevices.filter(outputDesc->routableDevices());
        bool mute = shouldMute && curDevices.containsAtLeastOne(devices) && curDevices != devices;
        bool doMute = false;

@@ -8179,7 +8213,7 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescr
            for (size_t j = 0; j < mOutputs.size(); j++) {
                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
                // skip output if it does not share any device with current output
                if (!desc->supportedDevices().containsAtLeastOne(outputDesc->supportedDevices())) {
                if (!desc->routableDevices().containsAtLeastOne(outputDesc->routableDevices())) {
                    continue;
                }
                ALOGVV("%s() output %s %s (curDevice %s)", __func__, desc->info().c_str(),
@@ -8260,7 +8294,7 @@ uint32_t AudioPolicyManager::setOutputDevices(const char *caller,
    }

    // filter devices according to output selected
    DeviceVector filteredDevices = outputDesc->filterSupportedDevices(devices);
    DeviceVector filteredDevices = outputDesc->filterRoutableDevices(devices);
    DeviceVector prevDevices = outputDesc->devices();
    DeviceVector availPrevDevices = mAvailableOutputDevices.filter(prevDevices);

@@ -8282,8 +8316,8 @@ uint32_t AudioPolicyManager::setOutputDevices(const char *caller,

    bool outputRouted = outputDesc->isRouted();

    // 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
    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not routable to/from current
    // output profile or if new device is not routable AND previous device(s) is(are) still
    // available (otherwise reset device must be done on the output)
    if (!devices.isEmpty() && filteredDevices.isEmpty() && !availPrevDevices.empty()) {
        ALOGV("%s: %s unsupported device %s for output", __func__, logPrefix.c_str(),
@@ -8460,6 +8494,11 @@ sp<IOProfile> AudioPolicyManager::getInputProfile(const sp<DeviceDescriptor> &de
        auto bestCompatibleScore = IOProfile::NO_MATCH;
        for (const auto& hwModule : mHwModules) {
            for (const auto& profile : hwModule->getInputProfiles()) {
                if (com::android::media::audioserver::enable_strict_port_routing_checks() &&
                      !profile->routesToDevice(device)) {
                    continue;
                }

                // profile->log();
                //updatedFormat = format;
                auto compatibleScore = profile->getCompatibilityScore(
@@ -9277,7 +9316,7 @@ sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
{
    for (const auto& device : devices) {
        // TODO: This should be checking if the profile supports the device combo.
        if (!profile->supportsDevice(device)) {
        if (!profile->routesToDevice(device)) {
            ALOGE("%s profile(%s) doesn't support device %#x", __func__, profile->getName().c_str(),
                  device->type());
            return nullptr;
@@ -9352,7 +9391,7 @@ sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
        }

    } else if (hasPrimaryOutput() && speaker != nullptr
            && mPrimaryOutput->supportsDevice(speaker) && !desc->supportsDevice(speaker)
            && mPrimaryOutput->routesToDevice(speaker) && !desc->routesToDevice(speaker)
            && ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
        // no duplicated output for:
        // - direct outputs
@@ -9476,7 +9515,7 @@ status_t AudioPolicyManager::getProfilesForDevices(const DeviceVector& devices,
        IOProfileCollection ioProfiles = isInput ? hwModule->getInputProfiles()
                                                 : hwModule->getOutputProfiles();
        for (const auto& profile : ioProfiles) {
            if (!profile->areAllDevicesSupported(devices) ||
            if (!profile->areAllDevicesRoutable(devices) ||
                    !profile->isCompatibleProfileForFlags(flags)) {
                continue;
            }
Loading