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

Commit cf84e596 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audiopolicy: Refactor and fix loops in AudioPolicyManager

  -- Use range for loops where possible.

  -- Replace some loops over DeviceVector with a call to already
     existing search function.

  -- Fix unsigned integer overflow in a loop that decrements
     the loop counter.

Change-Id: I2ab544b8176310c15c16c04b72c2800d8526e5a5
Test: compiles
parent 7e22e94d
Loading
Loading
Loading
Loading
+64 −95
Original line number Diff line number Diff line
@@ -183,14 +183,14 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
        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]);
            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(outputs[i]);
                    closeOutput(output);
                }
            }
            // check again after closing A2DP output to reset mA2dpSuspended if needed
@@ -499,9 +499,7 @@ uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_
        // FIXME: would be better to refine to only inputs whose profile connects to the
        // call TX device but this information is not in the audio patch and logic here must be
        // symmetric to the one in startInput()
        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()) {
            if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
                AudioSessionCollection activeSessions =
                        activeDesc->getAudioSessions(true /*activeOnly*/);
@@ -683,9 +681,7 @@ void AudioPolicyManager::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()) {
        audio_devices_t newDevice = getNewInputDevice(activeDesc);
        // Force new input selection if the new device can not be reached via current input
        if (activeDesc->mProfile->getSupportedDevices().types() &
@@ -722,8 +718,7 @@ sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
    sp<IOProfile> profile;

    for (const auto& hwModule : mHwModules) {
        for (size_t j = 0; j < hwModule->mOutputProfiles.size(); j++) {
            sp<IOProfile> curProfile = hwModule->mOutputProfiles[j];
        for (const auto& curProfile : hwModule->mOutputProfiles) {
            if (!curProfile->isCompatibleProfile(device, String8(""),
                    samplingRate, NULL /*updatedSamplingRate*/,
                    format, NULL /*updatedFormat*/,
@@ -824,12 +819,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
    // Explicit routing?
    sp<DeviceDescriptor> deviceDesc;
    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
        for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
            if (mAvailableOutputDevices[i]->getId() == *selectedDeviceId) {
                deviceDesc = mAvailableOutputDevices[i];
                break;
            }
        }
        deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
    }
    mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);

@@ -1030,21 +1020,21 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h
    // 4: the first output in the list

    if (outputs.size() == 0) {
        return 0;
        return AUDIO_IO_HANDLE_NONE;
    }
    if (outputs.size() == 1) {
        return outputs[0];
    }

    int maxCommonFlags = 0;
    audio_io_handle_t outputForFlags = 0;
    audio_io_handle_t outputForPrimary = 0;
    audio_io_handle_t outputForFormat = 0;
    audio_io_handle_t outputForFlags = AUDIO_IO_HANDLE_NONE;
    audio_io_handle_t outputForPrimary = AUDIO_IO_HANDLE_NONE;
    audio_io_handle_t outputForFormat = AUDIO_IO_HANDLE_NONE;
    audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
    audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;

    for (size_t i = 0; i < outputs.size(); i++) {
        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
    for (audio_io_handle_t output : outputs) {
        sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
        if (!outputDesc->isDuplicated()) {
            // if a valid format is specified, skip output if not compatible
            if (format != AUDIO_FORMAT_INVALID) {
@@ -1057,7 +1047,7 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h
                }
                if (AudioPort::isBetterFormatMatch(
                        outputDesc->mFormat, bestFormat, format)) {
                    outputForFormat = outputs[i];
                    outputForFormat = output;
                    bestFormat = outputDesc->mFormat;
                }
            }
@@ -1068,29 +1058,29 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h
                    if (format != AUDIO_FORMAT_INVALID
                            && AudioPort::isBetterFormatMatch(
                                    outputDesc->mFormat, bestFormatForFlags, format)) {
                        outputForFlags = outputs[i];
                        outputForFlags = output;
                        bestFormatForFlags = outputDesc->mFormat;
                    }
                } else {
                    outputForFlags = outputs[i];
                    outputForFlags = output;
                    maxCommonFlags = commonFlags;
                    bestFormatForFlags = outputDesc->mFormat;
                }
                ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
                ALOGV("selectOutput() commonFlags for output %d, %04x", output, commonFlags);
            }
            if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
                outputForPrimary = outputs[i];
                outputForPrimary = output;
            }
        }
    }

    if (outputForFlags != 0) {
    if (outputForFlags != AUDIO_IO_HANDLE_NONE) {
        return outputForFlags;
    }
    if (outputForFormat != 0) {
    if (outputForFormat != AUDIO_IO_HANDLE_NONE) {
        return outputForFormat;
    }
    if (outputForPrimary != 0) {
    if (outputForPrimary != AUDIO_IO_HANDLE_NONE) {
        return outputForPrimary;
    }

@@ -1448,12 +1438,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
    // Explicit routing?
    sp<DeviceDescriptor> deviceDesc;
    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
        for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
            if (mAvailableInputDevices[i]->getId() == *selectedDeviceId) {
                deviceDesc = mAvailableInputDevices[i];
                break;
            }
        }
        deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
    }
    mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);

@@ -1776,9 +1761,7 @@ bool AudioPolicyManager::isConcurentCaptureAllowed(const sp<AudioInputDescriptor
        return true;
    }

    Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
    for (size_t i = 0; i <  activeInputs.size(); i++) {
        sp<AudioInputDescriptor> activeInput = activeInputs[i];
    for (const auto& activeInput : mInputs.getActiveInputs()) {
        if (!isConcurrentSource(activeInput->inputSource(true)) &&
                !is_virtual_input_device(activeInput->mDevice)) {
            return false;
@@ -1864,9 +1847,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
        }

        Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
        for (size_t i = 0; i < activeInputs.size(); i++) {
            sp<AudioInputDescriptor> activeDesc = activeInputs[i];

        for (const auto& activeDesc : activeInputs) {
            if (is_virtual_input_device(activeDesc->mDevice)) {
                continue;
            }
@@ -1906,9 +1887,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
            inputDesc->isSoundTrigger() ? soundTriggerSupportsConcurrentCapture() : false;

        // if capture is allowed, preempt currently active HOTWORD captures
        for (size_t i = 0; i < activeInputs.size(); i++) {
            sp<AudioInputDescriptor> activeDesc = activeInputs[i];

        for (const auto& activeDesc : activeInputs) {
            if (is_virtual_input_device(activeDesc->mDevice)) {
                continue;
            }
@@ -2267,21 +2246,21 @@ audio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()
        audio_io_handle_t outputDeepBuffer = AUDIO_IO_HANDLE_NONE;
        audio_io_handle_t outputPrimary = AUDIO_IO_HANDLE_NONE;

        for (size_t i = 0; i < outputs.size(); i++) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
        for (audio_io_handle_t output : outputs) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
            if (activeOnly && !desc->isStreamActive(AUDIO_STREAM_MUSIC)) {
                continue;
            }
            ALOGV("selectOutputForMusicEffects activeOnly %d outputs[%zu] flags 0x%08x",
                  activeOnly, i, desc->mFlags);
            ALOGV("selectOutputForMusicEffects activeOnly %d output %d flags 0x%08x",
                  activeOnly, output, desc->mFlags);
            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
                outputOffloaded = outputs[i];
                outputOffloaded = output;
            }
            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
                outputDeepBuffer = outputs[i];
                outputDeepBuffer = output;
            }
            if ((desc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
                outputPrimary = outputs[i];
                outputPrimary = output;
            }
        }
        if (outputOffloaded != AUDIO_IO_HANDLE_NONE) {
@@ -2480,8 +2459,8 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
    status_t res = NO_ERROR;
    sp<HwModule> rSubmixModule;
    // examine each mix's route type
    for (size_t i = 0; i < mixes.size(); i++) {
        if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
    for (const auto& mix : mixes) {
        if ((mix.mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {

            if (rSubmixModule == 0) {
                rSubmixModule = mHwModules.getModuleFromName(
@@ -2492,7 +2471,7 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
                }
            }

            String8 address = mixes[i].mDeviceAddress;
            String8 address = mix.mDeviceAddress;

            if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
                res = INVALID_OPERATION;
@@ -2514,8 +2493,8 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
            rSubmixModule->removeOutputProfile(address);
            rSubmixModule->removeInputProfile(address);

        } if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
            if (mPolicyMixes.unregisterMix(mixes[i].mDeviceAddress) != NO_ERROR) {
        } if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
            if (mPolicyMixes.unregisterMix(mix.mDeviceAddress) != NO_ERROR) {
                res = INVALID_OPERATION;
                continue;
            }
@@ -2672,23 +2651,23 @@ status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
        // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
        // as they are used by stub HALs by convention
        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
            for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
                if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
            for (const auto& dev : mAvailableOutputDevices) {
                if (dev->type() == AUDIO_DEVICE_OUT_STUB) {
                    continue;
                }
                if (portsWritten < portsMax) {
                    mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
                    dev->toAudioPort(&ports[portsWritten++]);
                }
                (*num_ports)++;
            }
        }
        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
            for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
                if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
            for (const auto& dev : mAvailableInputDevices) {
                if (dev->type() == AUDIO_DEVICE_IN_STUB) {
                    continue;
                }
                if (portsWritten < portsMax) {
                    mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
                    dev->toAudioPort(&ports[portsWritten++]);
                }
                (*num_ports)++;
            }
@@ -3183,8 +3162,8 @@ void AudioPolicyManager::clearSessionRoutes(uid_t uid)
        }
    }
    // reroute outputs if necessary
    for (size_t i = 0; i < affectedStrategies.size(); i++) {
        checkStrategyRoute(affectedStrategies[i], AUDIO_IO_HANDLE_NONE);
    for (const auto& strategy : affectedStrategies) {
        checkStrategyRoute(strategy, AUDIO_IO_HANDLE_NONE);
    }

    // remove input routes associated with this uid
@@ -3206,8 +3185,8 @@ void AudioPolicyManager::clearSessionRoutes(uid_t uid)
            inputsToClose.add(inputDesc->mIoHandle);
        }
    }
    for (size_t i = 0; i < inputsToClose.size(); i++) {
        closeInput(inputsToClose[i]);
    for (const auto& input : inputsToClose) {
        closeInput(input);
    }
}

@@ -3384,8 +3363,8 @@ status_t AudioPolicyManager::setMasterMono(bool mono)
                offloaded.push(desc->mIoHandle);
            }
        }
        for (size_t i = 0; i < offloaded.size(); ++i) {
            closeOutput(offloaded[i]);
        for (const auto& handle : offloaded) {
            closeOutput(handle);
        }
    }
    // update master mono for all remaining outputs
@@ -3560,9 +3539,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
        // except for direct output streams that are only opened when they are actually
        // required by an app.
        // This also validates mAvailableOutputDevices list
        for (size_t j = 0; j < hwModule->mOutputProfiles.size(); j++) {
            const sp<IOProfile> outProfile = hwModule->mOutputProfiles[j];

        for (const auto& outProfile : hwModule->mOutputProfiles) {
            if (!outProfile->hasSupportedDevices()) {
                ALOGW("Output profile contains no device on module %s", hwModule->getName());
                continue;
@@ -3600,8 +3577,8 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
                      outputDesc->mDevice,
                      hwModule->getName());
            } else {
                for (size_t k = 0; k  < supportedDevices.size(); k++) {
                    ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
                for (const auto& dev : supportedDevices) {
                    ssize_t index = mAvailableOutputDevices.indexOf(dev);
                    // give a valid ID to an attached device once confirmed it is reachable
                    if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
                        mAvailableOutputDevices[index]->attach(hwModule);
@@ -3622,9 +3599,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
        }
        // open input streams needed to access attached devices to validate
        // mAvailableInputDevices list
        for (size_t j = 0; j < hwModule->mInputProfiles.size(); j++) {
            const sp<IOProfile> inProfile = hwModule->mInputProfiles[j];

        for (const auto& inProfile : hwModule->mInputProfiles) {
            if (!inProfile->hasSupportedDevices()) {
                ALOGW("Input profile contains no device on module %s", hwModule->getName());
                continue;
@@ -3648,9 +3623,8 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
                                              &input);

            if (status == NO_ERROR) {
                const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
                for (size_t k = 0; k  < supportedDevices.size(); k++) {
                    ssize_t index =  mAvailableInputDevices.indexOf(supportedDevices[k]);
                for (const auto& dev : inProfile->getSupportedDevices()) {
                    ssize_t index = mAvailableInputDevices.indexOf(dev);
                    // give a valid ID to an attached device once confirmed it is reachable
                    if (index >= 0) {
                        sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
@@ -4255,14 +4229,14 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
              strategy, srcOutputs[0], dstOutputs[0]);
        // mute strategy while moving tracks from one output to another
        for (size_t i = 0; i < srcOutputs.size(); i++) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
        for (audio_io_handle_t srcOut : srcOutputs) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOut);
            if (isStrategyActive(desc, strategy)) {
                setStrategyMute(strategy, true, desc);
                setStrategyMute(strategy, false, desc, MUTE_TIME_MS, newDevice);
            }
            sp<AudioSourceDescriptor> source =
                    getSourceForStrategyOnOutput(srcOutputs[i], strategy);
                    getSourceForStrategyOnOutput(srcOut, strategy);
            if (source != 0){
                connectAudioSource(source);
            }
@@ -4456,9 +4430,8 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre
        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
        audio_devices_t curDevices =
                getDeviceForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs);
        for (size_t i = 0; i < outputs.size(); i++) {
            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
        for (audio_io_handle_t output : getOutputsForDevice(curDevices, mOutputs)) {
            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
            if (outputDesc->isStreamActive((audio_stream_type_t)curStream)) {
                curDevices |= outputDesc->device();
            }
@@ -4943,8 +4916,7 @@ sp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
    // the best matching profile, not the first one.

    for (const auto& hwModule : mHwModules) {
        for (size_t j = 0; j < hwModule->mInputProfiles.size(); j++) {
            sp<IOProfile> profile = hwModule->mInputProfiles[j];
        for (const auto& profile : hwModule->mInputProfiles) {
            // profile->log();
            if (profile->isCompatibleProfile(device, address, samplingRate,
                                             &samplingRate /*updatedSamplingRate*/,
@@ -5424,7 +5396,7 @@ void AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
    bool supportsAC3 = false;
    bool supportsOtherSurround = false;
    bool supportsIEC61937 = false;
    for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
    for (ssize_t formatIndex = 0; formatIndex < (ssize_t)formats.size(); formatIndex++) {
        audio_format_t format = formats[formatIndex];
        switch (format) {
            case AUDIO_FORMAT_AC3:
@@ -5520,8 +5492,7 @@ void AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasks
    } else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
        bool supports5dot1 = false;
        // Are there any channel masks that can be considered "surround"?
        for (size_t maskIndex = 0; maskIndex < channelMasks.size(); maskIndex++) {
            audio_channel_mask_t channelMask = channelMasks[maskIndex];
        for (audio_channel_mask_t channelMask : channelMasks) {
            if ((channelMask & AUDIO_CHANNEL_OUT_5POINT1) == AUDIO_CHANNEL_OUT_5POINT1) {
                supports5dot1 = true;
                break;
@@ -5558,10 +5529,8 @@ void AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
        }
        profiles.setFormats(formats);
    }
    const FormatVector &supportedFormats = profiles.getSupportedFormats();

    for (size_t formatIndex = 0; formatIndex < supportedFormats.size(); formatIndex++) {
        audio_format_t format = supportedFormats[formatIndex];
    for (audio_format_t format : profiles.getSupportedFormats()) {
        ChannelsVector channelMasks;
        SampleRateVector samplingRates;
        AudioParameter requestedParameters;