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

Commit 1ef495d3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Revert "audio policy: add open and active count for IO profiles"""

parents ac4e764d 3974e3b2
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -34,7 +34,11 @@ class IOProfile : public AudioPort
{
public:
    IOProfile(const String8 &name, audio_port_role_t role)
        : AudioPort(name, AUDIO_PORT_TYPE_MIX, role) {}
        : AudioPort(name, AUDIO_PORT_TYPE_MIX, role),
          maxOpenCount((role == AUDIO_PORT_ROLE_SOURCE) ? 1 : 0),
          curOpenCount(0),
          maxActiveCount(1),
          curActiveCount(0) {}

    // For a Profile aka MixPort, tag name and name are equivalent.
    virtual const String8 getTagName() const { return getName(); }
@@ -103,6 +107,34 @@ public:

    const DeviceVector &getSupportedDevices() const { return mSupportedDevices; }

    bool canOpenNewIo() {
        if (maxOpenCount == 0 || curOpenCount < maxOpenCount) {
            return true;
        }
        return false;
    }

    bool canStartNewIo() {
        if (maxActiveCount == 0 || curActiveCount < maxActiveCount) {
            return true;
        }
        return false;
    }

    // Maximum number of input or output streams that can be simultaneously opened for this profile.
    // By convention 0 means no limit. To respect legacy behavior, initialized to 1 for output
    // profiles and 0 for input profiles
    uint32_t     maxOpenCount;
    // Number of streams currently opened for this profile.
    uint32_t     curOpenCount;
    // Maximum number of input or output streams that can be simultaneously active for this profile.
    // By convention 0 means no limit. To respect legacy behavior, initialized to 0 for output
    // profiles and 1 for input profiles
    uint32_t     maxActiveCount;
    // Number of streams currently active for this profile. This is not the number of active clients
    // (AudioTrack or AudioRecord) but the number of active HAL streams.
    uint32_t     curActiveCount;

private:
    DeviceVector mSupportedDevices; // supported devices: this input/output can be routed from/to
};
+5 −0
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ status_t AudioInputDescriptor::open(const audio_config_t *config,
        mFormat = lConfig.format;
        mId = AudioPort::getNextUniqueId();
        mIoHandle = *input;
        mProfile->curOpenCount++;
    }

    return status;
@@ -238,6 +239,10 @@ void AudioInputDescriptor::close()
{
    if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
        mClientInterface->closeInput(mIoHandle);
        LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
                            __FUNCTION__, mProfile->curOpenCount);
        mProfile->curOpenCount--;
        mIoHandle = AUDIO_IO_HANDLE_NONE;
    }
}

+6 −0
Original line number Diff line number Diff line
@@ -436,6 +436,7 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
        mFormat = lConfig.format;
        mId = AudioPort::getNextUniqueId();
        mIoHandle = *output;
        mProfile->curOpenCount++;
    }

    return status;
@@ -450,6 +451,11 @@ void SwAudioOutputDescriptor::close()
        mClientInterface->setParameters(mIoHandle, param.toString());

        mClientInterface->closeOutput(mIoHandle);

        LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
                            __FUNCTION__, mProfile->curOpenCount);
        mProfile->curOpenCount--;
        mIoHandle = AUDIO_IO_HANDLE_NONE;
    }
}

+10 −0
Original line number Diff line number Diff line
@@ -122,6 +122,16 @@ void IOProfile::dump(int fd)
    result.append("\n");
    write(fd, result.string(), result.size());
    mSupportedDevices.dump(fd, String8("Supported"), 4, false);

    result.clear();
    snprintf(buffer, SIZE, "\n    - maxOpenCount: %u - curOpenCount: %u\n",
             maxOpenCount, curOpenCount);
    result.append(buffer);
    snprintf(buffer, SIZE, "    - maxActiveCount: %u - curActiveCount: %u\n",
             maxActiveCount, curActiveCount);
    result.append(buffer);

    write(fd, result.string(), result.size());
}

void IOProfile::log()
+74 −22
Original line number Diff line number Diff line
@@ -887,37 +887,29 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
    }

    if (profile != 0) {
        sp<SwAudioOutputDescriptor> outputDesc = NULL;

        for (size_t i = 0; i < mOutputs.size(); i++) {
            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
                outputDesc = desc;
                // reuse direct output if currently open by the same client
                // and configured with same parameters
                if ((config->sample_rate == outputDesc->mSamplingRate) &&
                    audio_formats_match(config->format, outputDesc->mFormat) &&
                    (config->channel_mask == outputDesc->mChannelMask)) {
                  if (session == outputDesc->mDirectClientSession) {
                      outputDesc->mDirectOpenCount++;
                if ((config->sample_rate == desc->mSamplingRate) &&
                    audio_formats_match(config->format, desc->mFormat) &&
                    (config->channel_mask == desc->mChannelMask) &&
                    (session == desc->mDirectClientSession)) {
                    desc->mDirectOpenCount++;
                    ALOGV("getOutputForDevice() reusing direct output %d for session %d",
                        mOutputs.keyAt(i), session);
                    return mOutputs.keyAt(i);
                  } else {
                      ALOGV("getOutputForDevice() do not reuse direct output because"
                              "current client (%d) is not the same as requesting client (%d)",
                            outputDesc->mDirectClientSession, session);
                      goto non_direct_output;
                }
            }
        }
        }
        // close direct output if currently open and configured with different parameters
        if (outputDesc != NULL) {
            closeOutput(outputDesc->mIoHandle);

        if (!profile->canOpenNewIo()) {
            goto non_direct_output;
        }

        outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
        sp<SwAudioOutputDescriptor> outputDesc =
                new SwAudioOutputDescriptor(profile, mpClientInterface);

        DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
        String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
@@ -1080,6 +1072,13 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,

    sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);

    if (!outputDesc->isActive()) {
        if (!outputDesc->mProfile->canStartNewIo()) {
            return INVALID_OPERATION;
        }
        outputDesc->mProfile->curActiveCount++;
    }

    // Routing?
    mOutputRoutes.incRouteActivity(session);

@@ -1107,6 +1106,12 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,

    if (status != NO_ERROR) {
        mOutputRoutes.decRouteActivity(session);
        if (!outputDesc->isActive()) {
            LOG_ALWAYS_FATAL_IF(outputDesc->mProfile->curActiveCount < 1,
                                "%s invalid profile active count %u",
                                __FUNCTION__, outputDesc->mProfile->curActiveCount);
            outputDesc->mProfile->curActiveCount--;
        }
        return status;
    }
    // Automatically enable the remote submix input when output is started on a re routing mix
@@ -1295,7 +1300,15 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
        }
    }

    return stopSource(outputDesc, stream, forceDeviceUpdate);
    status_t status = stopSource(outputDesc, stream, forceDeviceUpdate);

    if (status == NO_ERROR && !outputDesc->isActive()) {
        LOG_ALWAYS_FATAL_IF(outputDesc->mProfile->curActiveCount < 1,
                            "%s invalid profile active count %u",
                            __FUNCTION__, outputDesc->mProfile->curActiveCount);
        outputDesc->mProfile->curActiveCount--;
    }
    return status;
}

status_t AudioPolicyManager::stopSource(const sp<AudioOutputDescriptor>& outputDesc,
@@ -1676,6 +1689,10 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
    }
#endif

    if (!profile->canOpenNewIo()) {
        return AUDIO_IO_HANDLE_NONE;
    }

    sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile, mpClientInterface);

    audio_config_t lConfig = AUDIO_CONFIG_INITIALIZER;
@@ -1913,6 +1930,13 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
        setInputDevice(input, device, true /* force */);

        if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
            if (!inputDesc->mProfile->canStartNewIo()) {
                mInputRoutes.decRouteActivity(session);
                audioSession->changeActiveCount(-1);
                return INVALID_OPERATION;
            }
            inputDesc->mProfile->curActiveCount++;

            // if input maps to a dynamic policy with an activity listener, notify of state change
            if ((inputDesc->mPolicyMix != NULL)
                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
@@ -1982,6 +2006,11 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
        if (inputDesc->isActive()) {
            setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
        } else {
            LOG_ALWAYS_FATAL_IF(inputDesc->mProfile->curActiveCount < 1,
                                "%s invalid profile active count %u",
                                __FUNCTION__, inputDesc->mProfile->curActiveCount);
            inputDesc->mProfile->curActiveCount--;

            // if input maps to a dynamic policy with an activity listener, notify of state change
            if ((inputDesc->mPolicyMix != NULL)
                    && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
@@ -3525,6 +3554,11 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
        // required by an app.
        // This also validates mAvailableOutputDevices list
        for (const auto& outProfile : hwModule->getOutputProfiles()) {
            if (!outProfile->canOpenNewIo()) {
                ALOGE("Invalid Output profile max open count %u for profile %s",
                      outProfile->maxOpenCount, outProfile->getTagName().c_str());
                continue;
            }
            if (!outProfile->hasSupportedDevices()) {
                ALOGW("Output profile contains no device on module %s", hwModule->getName());
                continue;
@@ -3585,6 +3619,11 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
        // open input streams needed to access attached devices to validate
        // mAvailableInputDevices list
        for (const auto& inProfile : hwModule->getInputProfiles()) {
            if (!inProfile->canOpenNewIo()) {
                ALOGE("Invalid Input profile max open count %u for profile %s",
                      inProfile->maxOpenCount, inProfile->getTagName().c_str());
                continue;
            }
            if (!inProfile->hasSupportedDevices()) {
                ALOGW("Input profile contains no device on module %s", hwModule->getName());
                continue;
@@ -3795,6 +3834,12 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
                continue;
            }

            if (!profile->canOpenNewIo()) {
                ALOGW("Max Output number %u already opened for this profile %s",
                      profile->maxOpenCount, profile->getTagName().c_str());
                continue;
            }

            ALOGV("opening output for device %08x with params %s profile %p name %s",
                  device, address.string(), profile.get(), profile->getName().string());
            desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
@@ -3991,6 +4036,7 @@ status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& de
        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {

            sp<IOProfile> profile = profiles[profile_index];

            // nothing to do if one input is already opened for this profile
            size_t input_index;
            for (input_index = 0; input_index < mInputs.size(); input_index++) {
@@ -4006,6 +4052,12 @@ status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& de
                continue;
            }

            if (!profile->canOpenNewIo()) {
                ALOGW("Max Input number %u already opened for this profile %s",
                      profile->maxOpenCount, profile->getTagName().c_str());
                continue;
            }

            desc = new AudioInputDescriptor(profile, mpClientInterface);
            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
            status_t status = desc->open(nullptr,