diff options
Diffstat (limited to 'services/audiopolicy/AudioPolicyManager.cpp')
-rw-r--r-- | services/audiopolicy/AudioPolicyManager.cpp | 672 |
1 files changed, 415 insertions, 257 deletions
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index 8c3af5b..61edac2 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -223,7 +223,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, index = mAvailableOutputDevices.add(devDesc); if (index >= 0) { mAvailableOutputDevices[index]->mId = nextUniqueId(); - HwModule *module = getModuleForDevice(device); + sp<HwModule> module = getModuleForDevice(device); ALOG_ASSERT(module != NULL, "setDeviceConnectionState():" "could not find HW module for device %08x", device); mAvailableOutputDevices[index]->mModule = module; @@ -260,7 +260,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, // outputs must be closed after checkOutputForAllStrategies() is executed if (!outputs.isEmpty()) { for (size_t i = 0; i < outputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); + sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); // 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) || @@ -311,7 +311,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, ALOGW("setDeviceConnectionState() device already connected: %d", device); return INVALID_OPERATION; } - HwModule *module = getModuleForDevice(device); + sp<HwModule> module = getModuleForDevice(device); if (module == NULL) { ALOGW("setDeviceConnectionState(): could not find HW module for device %08x", device); @@ -442,7 +442,7 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state) checkOutputForAllStrategies(); updateDevicesAndOutputs(); - AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); + sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); // force routing command to audio hardware when ending call // even if no device change is needed @@ -454,7 +454,7 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state) if (isStateInCall(state)) { nsecs_t sysTime = systemTime(); for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(i); + sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); // mute media and sonification strategies and delay device switch by the largest // latency of any output where either strategy is active. // This avoid sending the ring tone or music tail into the earpiece or headset. @@ -644,7 +644,7 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, if (mTestOutputs[mCurOutput] == 0) { ALOGV("getOutput() opening test output"); - AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); + sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); outputDesc->mDevice = mTestDevice; outputDesc->mSamplingRate = mTestSamplingRate; outputDesc->mFormat = mTestFormat; @@ -696,10 +696,10 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, } if (profile != 0) { - AudioOutputDescriptor *outputDesc = NULL; + sp<AudioOutputDescriptor> outputDesc = NULL; for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(i); + sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); if (!desc->isDuplicated() && (profile == desc->mProfile)) { outputDesc = desc; // reuse direct output if currently open and configured with same parameters @@ -747,7 +747,6 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, if (output != 0) { mpClientInterface->closeOutput(output); } - delete outputDesc; return 0; } audio_io_handle_t srcOutput = getOutputForEffect(); @@ -804,7 +803,7 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h audio_io_handle_t outputPrimary = 0; for (size_t i = 0; i < outputs.size(); i++) { - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); if (!outputDesc->isDuplicated()) { int commonFlags = popcount(outputDesc->mProfile->mFlags & flags); if (commonFlags > maxCommonFlags) { @@ -839,7 +838,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, return BAD_VALUE; } - AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); // increment usage count for this stream on the requested output: // NOTE that the usage count is the same for duplicated output and hardware output which is @@ -854,7 +853,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, uint32_t waitMs = 0; bool force = false; for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(i); + sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); if (desc != outputDesc) { // force a device change if any other output is managed by the same hw // module and has a current device selection that differs from selected device. @@ -907,7 +906,7 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, return BAD_VALUE; } - AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); // handle special case for sonification while in call if (isInCall()) { @@ -932,7 +931,7 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, // one being selected for this output for (size_t i = 0; i < mOutputs.size(); i++) { audio_io_handle_t curOutput = mOutputs.keyAt(i); - AudioOutputDescriptor *desc = mOutputs.valueAt(i); + sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); if (curOutput != output && desc->isActive() && outputDesc->sharesHwModuleWith(desc) && @@ -965,10 +964,9 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output) #ifdef AUDIO_POLICY_TEST int testIndex = testOutputIndex(output); if (testIndex != 0) { - AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); if (outputDesc->isActive()) { mpClientInterface->closeOutput(output); - delete mOutputs.valueAt(index); mOutputs.removeItem(output); mTestOutputs[testIndex] = 0; } @@ -976,7 +974,7 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output) } #endif //AUDIO_POLICY_TEST - AudioOutputDescriptor *desc = mOutputs.valueAt(index); + sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index); if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) { if (desc->mDirectOpenCount <= 0) { ALOGW("releaseOutput() invalid open count %d for output %d", @@ -1045,7 +1043,7 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, return 0; } - AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); + sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile); inputDesc->mInputSource = inputSource; inputDesc->mDevice = device; @@ -1069,7 +1067,6 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, if (input != 0) { mpClientInterface->closeInput(input); } - delete inputDesc; return 0; } addInput(input, inputDesc); @@ -1085,7 +1082,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input) ALOGW("startInput() unknown input %d", input); return BAD_VALUE; } - AudioInputDescriptor *inputDesc = mInputs.valueAt(index); + sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); #ifdef AUDIO_POLICY_TEST if (mTestInput == 0) @@ -1095,7 +1092,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input) // uses AUDIO_SOURCE_HOTWORD in which case it is closed. audio_io_handle_t activeInput = getActiveInput(); if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) { - AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput); + sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput); if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { ALOGW("startInput() preempting already started low-priority input %d", activeInput); stopInput(activeInput); @@ -1129,7 +1126,7 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input) ALOGW("stopInput() unknown input %d", input); return BAD_VALUE; } - AudioInputDescriptor *inputDesc = mInputs.valueAt(index); + sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); if (inputDesc->mRefCount == 0) { ALOGW("stopInput() input %d already stopped", input); @@ -1156,7 +1153,6 @@ void AudioPolicyManager::releaseInput(audio_io_handle_t input) return; } mpClientInterface->closeInput(input); - delete mInputs.valueAt(index); mInputs.removeItem(input); nextAudioPortGeneration(); mpClientInterface->onAudioPortListUpdate(); @@ -1265,7 +1261,7 @@ audio_io_handle_t AudioPolicyManager::selectOutputForEffects( audio_io_handle_t outputDeepBuffer = 0; for (size_t i = 0; i < outputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]); + sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags); if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { outputOffloaded = outputs[i]; @@ -1327,14 +1323,14 @@ status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, desc->name, io, strategy, session, id); ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); - EffectDescriptor *pDesc = new EffectDescriptor(); - memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); - pDesc->mIo = io; - pDesc->mStrategy = (routing_strategy)strategy; - pDesc->mSession = session; - pDesc->mEnabled = false; + sp<EffectDescriptor> effectDesc = new EffectDescriptor(); + memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t)); + effectDesc->mIo = io; + effectDesc->mStrategy = (routing_strategy)strategy; + effectDesc->mSession = session; + effectDesc->mEnabled = false; - mEffects.add(id, pDesc); + mEffects.add(id, effectDesc); return NO_ERROR; } @@ -1347,21 +1343,20 @@ status_t AudioPolicyManager::unregisterEffect(int id) return INVALID_OPERATION; } - EffectDescriptor *pDesc = mEffects.valueAt(index); + sp<EffectDescriptor> effectDesc = mEffects.valueAt(index); - setEffectEnabled(pDesc, false); + setEffectEnabled(effectDesc, false); - if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { + if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) { ALOGW("unregisterEffect() memory %d too big for total %d", - pDesc->mDesc.memoryUsage, mTotalEffectsMemory); - pDesc->mDesc.memoryUsage = mTotalEffectsMemory; + effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); + effectDesc->mDesc.memoryUsage = mTotalEffectsMemory; } - mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; + mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage; ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", - pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); + effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); mEffects.removeItem(id); - delete pDesc; return NO_ERROR; } @@ -1377,43 +1372,43 @@ status_t AudioPolicyManager::setEffectEnabled(int id, bool enabled) return setEffectEnabled(mEffects.valueAt(index), enabled); } -status_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) +status_t AudioPolicyManager::setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled) { - if (enabled == pDesc->mEnabled) { + if (enabled == effectDesc->mEnabled) { ALOGV("setEffectEnabled(%s) effect already %s", enabled?"true":"false", enabled?"enabled":"disabled"); return INVALID_OPERATION; } if (enabled) { - if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { + if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", - pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); + effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10); return INVALID_OPERATION; } - mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; + mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad; ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); } else { - if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { + if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) { ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", - pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); - pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; + effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); + effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; } - mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; + mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad; ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); } - pDesc->mEnabled = enabled; + effectDesc->mEnabled = enabled; return NO_ERROR; } bool AudioPolicyManager::isNonOffloadableEffectEnabled() { for (size_t i = 0; i < mEffects.size(); i++) { - const EffectDescriptor * const pDesc = mEffects.valueAt(i); - if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) && - ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { + sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); + if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) && + ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", - pDesc->mDesc.name, pDesc->mSession); + effectDesc->mDesc.name, effectDesc->mSession); return true; } } @@ -1424,7 +1419,7 @@ bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inP { nsecs_t sysTime = systemTime(); for (size_t i = 0; i < mOutputs.size(); i++) { - const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); + const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { return true; } @@ -1437,7 +1432,7 @@ bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, { nsecs_t sysTime = systemTime(); for (size_t i = 0; i < mOutputs.size(); i++) { - const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); + const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && outputDesc->isStreamActive(stream, inPastMs, sysTime)) { return true; @@ -1449,7 +1444,7 @@ bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, bool AudioPolicyManager::isSourceActive(audio_source_t source) const { for (size_t i = 0; i < mInputs.size(); i++) { - const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i); + const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i); if ((inputDescriptor->mInputSource == (int)source || (source == AUDIO_SOURCE_VOICE_RECOGNITION && inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) @@ -1674,10 +1669,10 @@ status_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused) return NO_ERROR; } -AudioPolicyManager::AudioOutputDescriptor *AudioPolicyManager::getOutputFromId( +sp<AudioPolicyManager::AudioOutputDescriptor> AudioPolicyManager::getOutputFromId( audio_port_handle_t id) const { - AudioOutputDescriptor *outputDesc = NULL; + sp<AudioOutputDescriptor> outputDesc = NULL; for (size_t i = 0; i < mOutputs.size(); i++) { outputDesc = mOutputs.valueAt(i); if (outputDesc->mId == id) { @@ -1687,10 +1682,10 @@ AudioPolicyManager::AudioOutputDescriptor *AudioPolicyManager::getOutputFromId( return outputDesc; } -AudioPolicyManager::AudioInputDescriptor *AudioPolicyManager::getInputFromId( +sp<AudioPolicyManager::AudioInputDescriptor> AudioPolicyManager::getInputFromId( audio_port_handle_t id) const { - AudioInputDescriptor *inputDesc = NULL; + sp<AudioInputDescriptor> inputDesc = NULL; for (size_t i = 0; i < mInputs.size(); i++) { inputDesc = mInputs.valueAt(i); if (inputDesc->mId == id) { @@ -1700,8 +1695,11 @@ AudioPolicyManager::AudioInputDescriptor *AudioPolicyManager::getInputFromId( return inputDesc; } -AudioPolicyManager::HwModule *AudioPolicyManager::getModuleForDevice(audio_devices_t device) const +sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleForDevice( + audio_devices_t device) const { + sp <HwModule> module; + for (size_t i = 0; i < mHwModules.size(); i++) { if (mHwModules[i]->mHandle == 0) { continue; @@ -1722,18 +1720,20 @@ AudioPolicyManager::HwModule *AudioPolicyManager::getModuleForDevice(audio_devic } } } - return NULL; + return module; } -AudioPolicyManager::HwModule *AudioPolicyManager::getModuleFromName(const char *name) const +sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleFromName(const char *name) const { + sp <HwModule> module; + for (size_t i = 0; i < mHwModules.size(); i++) { if (strcmp(mHwModules[i]->mName, name) == 0) { return mHwModules[i]; } } - return NULL; + return module; } @@ -1783,7 +1783,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, return BAD_VALUE; } // output mix to output device connection - AudioOutputDescriptor *outputDesc = getOutputFromId(patch->sources[0].id); + sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); if (outputDesc == NULL) { ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id); return BAD_VALUE; @@ -1832,7 +1832,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { // input device to input mix connection - AudioInputDescriptor *inputDesc = getInputFromId(patch->sinks[0].id); + sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); if (inputDesc == NULL) { return BAD_VALUE; } @@ -1957,7 +1957,7 @@ status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, struct audio_patch *patch = &patchDesc->mPatch; patchDesc->mUid = mUidCached; if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { - AudioOutputDescriptor *outputDesc = getOutputFromId(patch->sources[0].id); + sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id); if (outputDesc == NULL) { ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id); return BAD_VALUE; @@ -1970,7 +1970,7 @@ status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, NULL); } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { - AudioInputDescriptor *inputDesc = getInputFromId(patch->sinks[0].id); + sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id); if (inputDesc == NULL) { ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id); return BAD_VALUE; @@ -2035,27 +2035,24 @@ status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config * } ALOGV("setAudioPortConfig() on port handle %d", config->id); // Only support gain configuration for now - if (config->config_mask != AUDIO_PORT_CONFIG_GAIN || config->gain.index < 0) { - return BAD_VALUE; + if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) { + return INVALID_OPERATION; } - sp<AudioPort> portDesc; - struct audio_port_config portConfig; + sp<AudioPortConfig> audioPortConfig; if (config->type == AUDIO_PORT_TYPE_MIX) { if (config->role == AUDIO_PORT_ROLE_SOURCE) { - AudioOutputDescriptor *outputDesc = getOutputFromId(config->id); + sp<AudioOutputDescriptor> outputDesc = getOutputFromId(config->id); if (outputDesc == NULL) { return BAD_VALUE; } - portDesc = outputDesc->mProfile; - outputDesc->toAudioPortConfig(&portConfig); + audioPortConfig = outputDesc; } else if (config->role == AUDIO_PORT_ROLE_SINK) { - AudioInputDescriptor *inputDesc = getInputFromId(config->id); + sp<AudioInputDescriptor> inputDesc = getInputFromId(config->id); if (inputDesc == NULL) { return BAD_VALUE; } - portDesc = inputDesc->mProfile; - inputDesc->toAudioPortConfig(&portConfig); + audioPortConfig = inputDesc; } else { return BAD_VALUE; } @@ -2071,47 +2068,22 @@ status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config * if (deviceDesc == NULL) { return BAD_VALUE; } - portDesc = deviceDesc; - deviceDesc->toAudioPortConfig(&portConfig); + audioPortConfig = deviceDesc; } else { return BAD_VALUE; } - if ((size_t)config->gain.index >= portDesc->mGains.size()) { - return INVALID_OPERATION; - } - const struct audio_gain *gain = &portDesc->mGains[config->gain.index]->mGain; - if ((config->gain.mode & ~gain->mode) != 0) { - return BAD_VALUE; - } - if ((config->gain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { - if ((config->gain.values[0] < gain->min_value) || - (config->gain.values[0] > gain->max_value)) { - return BAD_VALUE; - } - } else { - if ((config->gain.channel_mask & ~gain->channel_mask) != 0) { - return BAD_VALUE; - } - size_t numValues = popcount(config->gain.channel_mask); - for (size_t i = 0; i < numValues; i++) { - if ((config->gain.values[i] < gain->min_value) || - (config->gain.values[i] > gain->max_value)) { - return BAD_VALUE; - } - } + struct audio_port_config backupConfig; + status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig); + if (status == NO_ERROR) { + struct audio_port_config newConfig; + audioPortConfig->toAudioPortConfig(&newConfig, config); + status = mpClientInterface->setAudioPortConfig(&newConfig, 0); } - if ((config->gain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { - if ((config->gain.ramp_duration_ms < gain->min_ramp_ms) || - (config->gain.ramp_duration_ms > gain->max_ramp_ms)) { - return BAD_VALUE; - } + if (status != NO_ERROR) { + audioPortConfig->applyAudioPortConfig(&backupConfig); } - portConfig.gain = config->gain; - - status_t status = mpClientInterface->setAudioPortConfig(&portConfig, 0); - return status; } @@ -2230,7 +2202,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa audio_devices_t profileTypes = outProfile->mSupportedDevices.types(); if ((profileTypes & outputDeviceTypes) && ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) { - AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile); + sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile); outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mDeviceType & profileTypes); audio_io_handle_t output = mpClientInterface->openOutput( @@ -2245,7 +2217,6 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa ALOGW("Cannot open output stream for device %08x on hw module %s", outputDesc->mDevice, mHwModules[i]->mName); - delete outputDesc; } else { for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; @@ -2282,7 +2253,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa audio_devices_t profileTypes = inProfile->mSupportedDevices.types(); if (profileTypes & inputDeviceTypes) { - AudioInputDescriptor *inputDesc = new AudioInputDescriptor(inProfile); + sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile); inputDesc->mInputSource = AUDIO_SOURCE_MIC; inputDesc->mDevice = inProfile->mSupportedDevices[0]->mDeviceType; @@ -2310,7 +2281,6 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa inputDesc->mDevice, mHwModules[i]->mName); } - delete inputDesc; } } } @@ -2372,17 +2342,15 @@ AudioPolicyManager::~AudioPolicyManager() #endif //AUDIO_POLICY_TEST for (size_t i = 0; i < mOutputs.size(); i++) { mpClientInterface->closeOutput(mOutputs.keyAt(i)); - delete mOutputs.valueAt(i); } for (size_t i = 0; i < mInputs.size(); i++) { mpClientInterface->closeInput(mInputs.keyAt(i)); - delete mInputs.valueAt(i); - } - for (size_t i = 0; i < mHwModules.size(); i++) { - delete mHwModules[i]; } mAvailableOutputDevices.clear(); mAvailableInputDevices.clear(); + mOutputs.clear(); + mInputs.clear(); + mHwModules.clear(); } status_t AudioPolicyManager::initCheck() @@ -2486,15 +2454,14 @@ bool AudioPolicyManager::threadLoop() if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) { param.remove(String8("test_cmd_policy_reopen")); - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); mpClientInterface->closeOutput(mPrimaryOutput); audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; - delete mOutputs.valueFor(mPrimaryOutput); mOutputs.removeItem(mPrimaryOutput); - AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); + sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL); outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, &outputDesc->mDevice, @@ -2542,7 +2509,7 @@ int AudioPolicyManager::testOutputIndex(audio_io_handle_t output) // --- -void AudioPolicyManager::addOutput(audio_io_handle_t output, AudioOutputDescriptor *outputDesc) +void AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc) { outputDesc->mIoHandle = output; outputDesc->mId = nextUniqueId(); @@ -2550,7 +2517,7 @@ void AudioPolicyManager::addOutput(audio_io_handle_t output, AudioOutputDescript nextAudioPortGeneration(); } -void AudioPolicyManager::addInput(audio_io_handle_t input, AudioInputDescriptor *inputDesc) +void AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc) { inputDesc->mIoHandle = input; inputDesc->mId = nextUniqueId(); @@ -2571,7 +2538,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, SortedVector<audio_io_handle_t>& outputs, const String8 address) { - AudioOutputDescriptor *desc; + sp<AudioOutputDescriptor> desc; if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { // first list already open outputs that can be routed to this device @@ -2714,7 +2681,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, mPrimaryOutput); if (duplicatedOutput != 0) { // add duplicated output descriptor - AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL); + sp<AudioOutputDescriptor> dupOutputDesc = new AudioOutputDescriptor(NULL); dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput); dupOutputDesc->mOutput2 = mOutputs.valueFor(output); dupOutputDesc->mSamplingRate = desc->mSamplingRate; @@ -2736,7 +2703,6 @@ status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device, } if (output == 0) { ALOGW("checkOutputsForDevice() could not open output for device %x", device); - delete desc; profiles.removeAt(profile_index); profile_index--; } else { @@ -2796,7 +2762,7 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, SortedVector<audio_io_handle_t>& inputs, const String8 address) { - AudioInputDescriptor *desc; + sp<AudioInputDescriptor> desc; if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { // first list already open inputs that can be routed to this device for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { @@ -2911,7 +2877,6 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, if (input == 0) { ALOGW("checkInputsForDevice() could not open input for device 0x%X", device); - delete desc; profiles.removeAt(profile_index); profile_index--; } else { @@ -2972,7 +2937,7 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output) { ALOGV("closeOutput(%d)", output); - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); if (outputDesc == NULL) { ALOGW("closeOutput() unknown output %d", output); return; @@ -2980,11 +2945,11 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output) // look for duplicated outputs connected to the output being removed. for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i); + sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i); if (dupOutputDesc->isDuplicated() && (dupOutputDesc->mOutput1 == outputDesc || dupOutputDesc->mOutput2 == outputDesc)) { - AudioOutputDescriptor *outputDesc2; + sp<AudioOutputDescriptor> outputDesc2; if (dupOutputDesc->mOutput1 == outputDesc) { outputDesc2 = dupOutputDesc->mOutput2; } else { @@ -3002,7 +2967,6 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output) ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); mpClientInterface->closeOutput(duplicatedOutput); - delete mOutputs.valueFor(duplicatedOutput); mOutputs.removeItem(duplicatedOutput); } } @@ -3012,14 +2976,13 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output) mpClientInterface->setParameters(output, param.toString()); mpClientInterface->closeOutput(output); - delete outputDesc; mOutputs.removeItem(output); mPreviousOutputs = mOutputs; nextAudioPortGeneration(); } SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device, - DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) + DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs) { SortedVector<audio_io_handle_t> outputs; @@ -3061,7 +3024,7 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) strategy, srcOutputs[0], dstOutputs[0]); // mute strategy while moving tracks from one output to another for (size_t i = 0; i < srcOutputs.size(); i++) { - AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); + sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]); if (desc->isStrategyActive(strategy)) { setStrategyMute(strategy, true, srcOutputs[i]); setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); @@ -3073,17 +3036,17 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs); SortedVector<audio_io_handle_t> moved; for (size_t i = 0; i < mEffects.size(); i++) { - EffectDescriptor *desc = mEffects.valueAt(i); - if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX && - desc->mIo != fxOutput) { - if (moved.indexOf(desc->mIo) < 0) { + sp<EffectDescriptor> effectDesc = mEffects.valueAt(i); + if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX && + effectDesc->mIo != fxOutput) { + if (moved.indexOf(effectDesc->mIo) < 0) { ALOGV("checkOutputForStrategy() moving effect %d to output %d", mEffects.keyAt(i), fxOutput); - mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo, + mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo, fxOutput); - moved.add(desc->mIo); + moved.add(effectDesc->mIo); } - desc->mIo = fxOutput; + effectDesc->mIo = fxOutput; } } } @@ -3109,7 +3072,7 @@ void AudioPolicyManager::checkOutputForAllStrategies() audio_io_handle_t AudioPolicyManager::getA2dpOutput() { for (size_t i = 0; i < mOutputs.size(); i++) { - AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { return mOutputs.keyAt(i); } @@ -3167,7 +3130,7 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, { audio_devices_t device = AUDIO_DEVICE_NONE; - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle); if (index >= 0) { @@ -3213,7 +3176,7 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) { - AudioInputDescriptor *inputDesc = mInputs.valueFor(input); + sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle); if (index >= 0) { @@ -3247,7 +3210,7 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre devices = getDeviceForStrategy(strategy, true /*fromCache*/); SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs); for (size_t i = 0; i < outputs.size(); i++) { - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); if (outputDesc->isStrategyActive(strategy)) { devices = outputDesc->device(); break; @@ -3514,7 +3477,7 @@ void AudioPolicyManager::updateDevicesAndOutputs() mPreviousOutputs = mOutputs; } -uint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, +uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc, audio_devices_t prevDevice, uint32_t delayMs) { @@ -3543,7 +3506,7 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *ou } if (doMute) { for (size_t j = 0; j < mOutputs.size(); j++) { - AudioOutputDescriptor *desc = mOutputs.valueAt(j); + sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j); // skip output if it does not share any device with current output if ((desc->supportedDevices() & outputDesc->supportedDevices()) == AUDIO_DEVICE_NONE) { @@ -3601,7 +3564,7 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, audio_patch_handle_t *patchHandle) { ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); AudioParameter param; uint32_t muteWaitMs; @@ -3703,7 +3666,7 @@ status_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output, int delayMs, audio_patch_handle_t *patchHandle) { - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); ssize_t index; if (patchHandle) { index = mAudioPatches.indexOfKey(*patchHandle); @@ -3730,7 +3693,7 @@ status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, { status_t status = NO_ERROR; - AudioInputDescriptor *inputDesc = mInputs.valueFor(input); + sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) { inputDesc->mDevice = device; @@ -3785,7 +3748,7 @@ status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input, audio_patch_handle_t *patchHandle) { - AudioInputDescriptor *inputDesc = mInputs.valueFor(input); + sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input); ssize_t index; if (patchHandle) { index = mAudioPatches.indexOfKey(*patchHandle); @@ -3899,7 +3862,7 @@ bool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) audio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) { for (size_t i = 0; i < mInputs.size(); i++) { - const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i); + const sp<AudioInputDescriptor> input_descriptor = mInputs.valueAt(i); if ((input_descriptor->mRefCount > 0) && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { return mInputs.keyAt(i); @@ -4144,7 +4107,7 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream, audio_devices_t device) { float volume = 1.0; - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); StreamDescriptor &streamDesc = mStreams[stream]; if (device == AUDIO_DEVICE_NONE) { @@ -4300,7 +4263,7 @@ void AudioPolicyManager::setStreamMute(audio_stream_type_t stream, audio_devices_t device) { StreamDescriptor &streamDesc = mStreams[stream]; - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); if (device == AUDIO_DEVICE_NONE) { device = outputDesc->device(); } @@ -4345,7 +4308,7 @@ void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream, const routing_strategy stream_strategy = getStrategy(stream); if ((stream_strategy == STRATEGY_SONIFICATION) || ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) { - AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); + sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput); ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", stream, starting, outputDesc->mDevice, stateChange); if (outputDesc->mRefCount[stream]) { @@ -4403,8 +4366,7 @@ uint32_t AudioPolicyManager::getMaxEffectsMemory() AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( const sp<IOProfile>& profile) - : mId(0), mIoHandle(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), - mChannelMask(0), mLatency(0), + : mId(0), mIoHandle(0), mLatency(0), mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) { @@ -4419,9 +4381,13 @@ AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( mStrategyMutedByDevice[i] = false; } if (profile != NULL) { + mAudioPort = profile; mSamplingRate = profile->mSamplingRates[0]; mFormat = profile->mFormats[0]; mChannelMask = profile->mChannelMasks[0]; + if (profile->mGains.size() > 0) { + profile->mGains[0]->getDefaultConfig(&mGain); + } mFlags = profile->mFlags; } } @@ -4445,7 +4411,7 @@ uint32_t AudioPolicyManager::AudioOutputDescriptor::latency() } bool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith( - const AudioOutputDescriptor *outputDesc) + const sp<AudioOutputDescriptor> outputDesc) { if (isDuplicated()) { return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); @@ -4528,31 +4494,16 @@ void AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig( struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig) const { - dstConfig->id = mId; - dstConfig->role = AUDIO_PORT_ROLE_SOURCE; - dstConfig->type = AUDIO_PORT_TYPE_MIX; - dstConfig->sample_rate = mSamplingRate; - dstConfig->channel_mask = mChannelMask; - dstConfig->format = mFormat; - dstConfig->gain.index = -1; dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| - AUDIO_PORT_CONFIG_FORMAT; - // use supplied variable configuration parameters if any + AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; if (srcConfig != NULL) { - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { - dstConfig->sample_rate = srcConfig->sample_rate; - } - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { - dstConfig->channel_mask = srcConfig->channel_mask; - } - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { - dstConfig->format = srcConfig->format; - } - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { - dstConfig->gain = srcConfig->gain; - dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; - } + dstConfig->config_mask &= srcConfig->config_mask; } + AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); + + dstConfig->id = mId; + dstConfig->role = AUDIO_PORT_ROLE_SOURCE; + dstConfig->type = AUDIO_PORT_TYPE_MIX; dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; dstConfig->ext.mix.handle = mIoHandle; dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; @@ -4603,15 +4554,22 @@ status_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) // --- AudioInputDescriptor class implementation AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile) - : mId(0), mIoHandle(0), mSamplingRate(0), - mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0), + : mId(0), mIoHandle(0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0), mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile) { if (profile != NULL) { + mAudioPort = profile; mSamplingRate = profile->mSamplingRates[0]; mFormat = profile->mFormats[0]; mChannelMask = profile->mChannelMasks[0]; + if (profile->mGains.size() > 0) { + profile->mGains[0]->getDefaultConfig(&mGain); + } + } else { + mSamplingRate = 0; + mFormat = AUDIO_FORMAT_DEFAULT; + mChannelMask = 0; } } @@ -4619,31 +4577,17 @@ void AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig( struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig) const { - dstConfig->id = mId; - dstConfig->role = AUDIO_PORT_ROLE_SINK; - dstConfig->type = AUDIO_PORT_TYPE_MIX; - dstConfig->sample_rate = mSamplingRate; - dstConfig->channel_mask = mChannelMask; - dstConfig->format = mFormat; - dstConfig->gain.index = -1; dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| - AUDIO_PORT_CONFIG_FORMAT; - // use supplied variable configuration parameters if any + AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; if (srcConfig != NULL) { - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { - dstConfig->sample_rate = srcConfig->sample_rate; - } - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { - dstConfig->channel_mask = srcConfig->channel_mask; - } - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { - dstConfig->format = srcConfig->format; - } - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { - dstConfig->gain = srcConfig->gain; - dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; - } + dstConfig->config_mask &= srcConfig->config_mask; } + + AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); + + dstConfig->id = mId; + dstConfig->role = AUDIO_PORT_ROLE_SINK; + dstConfig->type = AUDIO_PORT_TYPE_MIX; dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle; dstConfig->ext.mix.handle = mIoHandle; dstConfig->ext.mix.usecase.source = mInputSource; @@ -4745,7 +4689,8 @@ status_t AudioPolicyManager::EffectDescriptor::dump(int fd) // --- HwModule class implementation AudioPolicyManager::HwModule::HwModule(const char *name) - : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0) + : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), + mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0) { } @@ -4904,6 +4849,8 @@ void AudioPolicyManager::HwModule::dump(int fd) result.append(buffer); snprintf(buffer, SIZE, " - handle: %d\n", mHandle); result.append(buffer); + snprintf(buffer, SIZE, " - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF); + result.append(buffer); write(fd, result.string(), result.size()); if (mOutputProfiles.size()) { write(fd, " - outputs:\n", strlen(" - outputs:\n")); @@ -4931,6 +4878,15 @@ void AudioPolicyManager::HwModule::dump(int fd) // --- AudioPort class implementation + +AudioPolicyManager::AudioPort::AudioPort(const String8& name, audio_port_type_t type, + audio_port_role_t role, const sp<HwModule>& module) : + mName(name), mType(type), mRole(role), mModule(module) +{ + mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) || + ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK)); +} + void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const { port->role = mRole; @@ -5066,18 +5022,17 @@ audio_gain_mode_t AudioPolicyManager::AudioPort::loadGainMode(char *name) return mode; } -void AudioPolicyManager::AudioPort::loadGain(cnode *root) +void AudioPolicyManager::AudioPort::loadGain(cnode *root, int index) { cnode *node = root->first_child; - sp<AudioGain> gain = new AudioGain(); + sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask); while (node) { if (strcmp(node->name, GAIN_MODE) == 0) { gain->mGain.mode = loadGainMode((char *)node->value); } else if (strcmp(node->name, GAIN_CHANNELS) == 0) { - if ((mType == AUDIO_PORT_TYPE_DEVICE && mRole == AUDIO_PORT_ROLE_SOURCE) || - (mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK)) { + if (mUseInChannelMask) { gain->mGain.channel_mask = (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable, ARRAY_SIZE(sInChannelsNameToEnumTable), @@ -5116,13 +5071,53 @@ void AudioPolicyManager::AudioPort::loadGain(cnode *root) void AudioPolicyManager::AudioPort::loadGains(cnode *root) { cnode *node = root->first_child; + int index = 0; while (node) { ALOGV("loadGains() loading gain %s", node->name); - loadGain(node); + loadGain(node, index++); node = node->next; } } +status_t AudioPolicyManager::AudioPort::checkSamplingRate(uint32_t samplingRate) const +{ + for (size_t i = 0; i < mSamplingRates.size(); i ++) { + if (mSamplingRates[i] == samplingRate) { + return NO_ERROR; + } + } + return BAD_VALUE; +} + +status_t AudioPolicyManager::AudioPort::checkChannelMask(audio_channel_mask_t channelMask) const +{ + for (size_t i = 0; i < mChannelMasks.size(); i ++) { + if (mChannelMasks[i] == channelMask) { + return NO_ERROR; + } + } + return BAD_VALUE; +} + +status_t AudioPolicyManager::AudioPort::checkFormat(audio_format_t format) const +{ + for (size_t i = 0; i < mFormats.size(); i ++) { + if (mFormats[i] == format) { + return NO_ERROR; + } + } + return BAD_VALUE; +} + +status_t AudioPolicyManager::AudioPort::checkGain(const struct audio_gain_config *gainConfig, + int index) const +{ + if (index < 0 || (size_t)index >= mGains.size()) { + return BAD_VALUE; + } + return mGains[index]->checkConfig(gainConfig); +} + void AudioPolicyManager::AudioPort::dump(int fd, int spaces) const { const size_t SIZE = 256; @@ -5181,11 +5176,72 @@ void AudioPolicyManager::AudioPort::dump(int fd, int spaces) const // --- AudioGain class implementation -AudioPolicyManager::AudioGain::AudioGain() +AudioPolicyManager::AudioGain::AudioGain(int index, bool useInChannelMask) { + mIndex = index; + mUseInChannelMask = useInChannelMask; memset(&mGain, 0, sizeof(struct audio_gain)); } +void AudioPolicyManager::AudioGain::getDefaultConfig(struct audio_gain_config *config) +{ + config->index = mIndex; + config->mode = mGain.mode; + config->channel_mask = mGain.channel_mask; + if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { + config->values[0] = mGain.default_value; + } else { + uint32_t numValues; + if (mUseInChannelMask) { + numValues = audio_channel_count_from_in_mask(mGain.channel_mask); + } else { + numValues = audio_channel_count_from_out_mask(mGain.channel_mask); + } + for (size_t i = 0; i < numValues; i++) { + config->values[i] = mGain.default_value; + } + } + if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { + config->ramp_duration_ms = mGain.min_ramp_ms; + } +} + +status_t AudioPolicyManager::AudioGain::checkConfig(const struct audio_gain_config *config) +{ + if ((config->mode & ~mGain.mode) != 0) { + return BAD_VALUE; + } + if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) { + if ((config->values[0] < mGain.min_value) || + (config->values[0] > mGain.max_value)) { + return BAD_VALUE; + } + } else { + if ((config->channel_mask & ~mGain.channel_mask) != 0) { + return BAD_VALUE; + } + uint32_t numValues; + if (mUseInChannelMask) { + numValues = audio_channel_count_from_in_mask(config->channel_mask); + } else { + numValues = audio_channel_count_from_out_mask(config->channel_mask); + } + for (size_t i = 0; i < numValues; i++) { + if ((config->values[i] < mGain.min_value) || + (config->values[i] > mGain.max_value)) { + return BAD_VALUE; + } + } + } + if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) { + if ((config->ramp_duration_ms < mGain.min_ramp_ms) || + (config->ramp_duration_ms > mGain.max_ramp_ms)) { + return BAD_VALUE; + } + } + return NO_ERROR; +} + void AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const { const size_t SIZE = 256; @@ -5214,10 +5270,116 @@ void AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const write(fd, result.string(), result.size()); } +// --- AudioPortConfig class implementation + +AudioPolicyManager::AudioPortConfig::AudioPortConfig() +{ + mSamplingRate = 0; + mChannelMask = AUDIO_CHANNEL_NONE; + mFormat = AUDIO_FORMAT_INVALID; + mGain.index = -1; +} + +status_t AudioPolicyManager::AudioPortConfig::applyAudioPortConfig( + const struct audio_port_config *config, + struct audio_port_config *backupConfig) +{ + struct audio_port_config localBackupConfig; + status_t status = NO_ERROR; + + localBackupConfig.config_mask = config->config_mask; + toAudioPortConfig(&localBackupConfig); + + if (mAudioPort == 0) { + status = NO_INIT; + goto exit; + } + if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { + status = mAudioPort->checkSamplingRate(config->sample_rate); + if (status != NO_ERROR) { + goto exit; + } + mSamplingRate = config->sample_rate; + } + if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { + status = mAudioPort->checkChannelMask(config->channel_mask); + if (status != NO_ERROR) { + goto exit; + } + mChannelMask = config->channel_mask; + } + if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) { + status = mAudioPort->checkFormat(config->format); + if (status != NO_ERROR) { + goto exit; + } + mFormat = config->format; + } + if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) { + status = mAudioPort->checkGain(&config->gain, config->gain.index); + if (status != NO_ERROR) { + goto exit; + } + mGain = config->gain; + } + +exit: + if (status != NO_ERROR) { + applyAudioPortConfig(&localBackupConfig); + } + if (backupConfig != NULL) { + *backupConfig = localBackupConfig; + } + return status; +} + +void AudioPolicyManager::AudioPortConfig::toAudioPortConfig( + struct audio_port_config *dstConfig, + const struct audio_port_config *srcConfig) const +{ + if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { + dstConfig->sample_rate = mSamplingRate; + if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) { + dstConfig->sample_rate = srcConfig->sample_rate; + } + } else { + dstConfig->sample_rate = 0; + } + if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { + dstConfig->channel_mask = mChannelMask; + if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) { + dstConfig->channel_mask = srcConfig->channel_mask; + } + } else { + dstConfig->channel_mask = AUDIO_CHANNEL_NONE; + } + if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { + dstConfig->format = mFormat; + if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) { + dstConfig->format = srcConfig->format; + } + } else { + dstConfig->format = AUDIO_FORMAT_INVALID; + } + if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { + dstConfig->gain = mGain; + if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) { + dstConfig->gain = srcConfig->gain; + } + } else { + dstConfig->gain.index = -1; + } + if (dstConfig->gain.index != -1) { + dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; + } else { + dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN; + } +} + // --- IOProfile class implementation AudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role, - HwModule *module) + const sp<HwModule>& module) : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module), mFlags((audio_output_flags_t)0) { } @@ -5245,32 +5407,13 @@ bool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device, if ((mFlags & flags) != flags) { return false; } - size_t i; - for (i = 0; i < mSamplingRates.size(); i++) - { - if (mSamplingRates[i] == samplingRate) { - break; - } - } - if (i == mSamplingRates.size()) { + if (checkSamplingRate(samplingRate) != NO_ERROR) { return false; } - for (i = 0; i < mFormats.size(); i++) - { - if (mFormats[i] == format) { - break; - } - } - if (i == mFormats.size()) { + if (checkChannelMask(channelMask) != NO_ERROR) { return false; } - for (i = 0; i < mChannelMasks.size(); i++) - { - if (mChannelMasks[i] == channelMask) { - break; - } - } - if (i == mChannelMasks.size()) { + if (checkFormat(format) != NO_ERROR) { return false; } return true; @@ -5322,6 +5465,21 @@ void AudioPolicyManager::IOProfile::log() // --- DeviceDescriptor implementation + +AudioPolicyManager::DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) : + AudioPort(name, AUDIO_PORT_TYPE_DEVICE, + audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : + AUDIO_PORT_ROLE_SOURCE, + NULL), + mDeviceType(type), mAddress(""), + mChannelMask(AUDIO_CHANNEL_NONE), mId(0) +{ + mAudioPort = this; + if (mGains.size() > 0) { + mGains[0]->getDefaultConfig(&mGain); + } +} + bool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const { // Devices are considered equal if they: @@ -5486,23 +5644,17 @@ void AudioPolicyManager::DeviceDescriptor::toAudioPortConfig( struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig) const { + dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN; + if (srcConfig != NULL) { + dstConfig->config_mask &= srcConfig->config_mask; + } + + AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); + dstConfig->id = mId; dstConfig->role = audio_is_output_device(mDeviceType) ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE; dstConfig->type = AUDIO_PORT_TYPE_DEVICE; - dstConfig->channel_mask = mChannelMask; - dstConfig->gain.index = -1; - dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK; - // use supplied variable configuration parameters if any - if (srcConfig != NULL) { - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { - dstConfig->channel_mask = srcConfig->channel_mask; - } - if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { - dstConfig->gain = srcConfig->gain; - dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; - } - } dstConfig->ext.device.type = mDeviceType; dstConfig->ext.device.hw_module = mModule->mHandle; strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN); @@ -5598,7 +5750,7 @@ void AudioPolicyManager::loadHwModule(cnode *root) { status_t status = NAME_NOT_FOUND; cnode *node; - HwModule *module = new HwModule(root->name); + sp<HwModule> module = new HwModule(root->name); node = config_find(root, DEVICES_TAG); if (node != NULL) { @@ -5640,8 +5792,6 @@ void AudioPolicyManager::loadHwModule(cnode *root) if (status == NO_ERROR) { mHwModules.add(module); - } else { - delete module; } } @@ -5660,9 +5810,10 @@ void AudioPolicyManager::loadHwModules(cnode *root) } } -void AudioPolicyManager::loadGlobalConfig(cnode *root, HwModule *module) +void AudioPolicyManager::loadGlobalConfig(cnode *root, const sp<HwModule>& module) { cnode *node = config_find(root, GLOBAL_CONFIG_TAG); + if (node == NULL) { return; } @@ -5695,6 +5846,12 @@ void AudioPolicyManager::loadGlobalConfig(cnode *root, HwModule *module) } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { mSpeakerDrcEnabled = stringToBool((char *)node->value); ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); + } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) { + uint32_t major, minor; + sscanf((char *)node->value, "%u.%u", &major, &minor); + module->mHalVersion = HARDWARE_DEVICE_API_VERSION(major, minor); + ALOGV("loadGlobalConfig() mHalVersion = %04x major %u minor %u", + module->mHalVersion, major, minor); } node = node->next; } @@ -5726,9 +5883,10 @@ status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) void AudioPolicyManager::defaultAudioPolicyConfig(void) { - HwModule *module; + sp<HwModule> module; sp<IOProfile> profile; - sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_IN_BUILTIN_MIC); + sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""), + AUDIO_DEVICE_IN_BUILTIN_MIC); mAvailableOutputDevices.add(mDefaultOutputDevice); mAvailableInputDevices.add(defaultInputDevice); |