Loading services/audiopolicy/common/managerdefinitions/include/IOProfile.h +33 −1 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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 }; Loading services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } } Loading services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } } Loading services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -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() Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +74 −22 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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++) { Loading @@ -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, Loading Loading
services/audiopolicy/common/managerdefinitions/include/IOProfile.h +33 −1 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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 }; Loading
services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } } Loading
services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } } Loading
services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -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() Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +74 −22 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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)) { Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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++) { Loading @@ -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, Loading