Loading services/audiopolicy/AudioPolicyManager.cpp +97 −43 Original line number Diff line number Diff line Loading @@ -899,14 +899,13 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, mPolicyMixes[i]->mMix.mRegistrationId.string(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { desc = mPolicyMixes[i]->mOutput; break; } } if (desc != 0) { if (!audio_is_linear_pcm(format)) { return BAD_VALUE; } desc->mPolicyMixAddress = mPolicyMixes[i]->mMix.mRegistrationId; desc->mPolicyMix = &mPolicyMixes[i]->mMix; *stream = streamTypefromAttributesInt(&attributes); *output = desc->mIoHandle; ALOGV("getOutputForAttr() returns output %d", *output); Loading Loading @@ -1227,8 +1226,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, if (outputDesc->mRefCount[stream] == 1) { // starting an output being rerouted? audio_devices_t newDevice; if (outputDesc->mPolicyMixAddress != String8("") && outputDesc->mPolicyMixAddress != String8("0")) { if (outputDesc->mPolicyMix != NULL) { newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX; } else { newDevice = getNewOutputDevice(output, false /*fromCache*/); Loading Loading @@ -1275,6 +1273,16 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, // update the outputs if starting an output with a stream that can affect notification // routing handleNotificationRoutingForStream(stream); // Automatically enable the remote submix input when output is started on a re routing mix // of type MIX_TYPE_RECORDERS if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL && outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, outputDesc->mPolicyMix->mRegistrationId); } if (waitMs > muteWaitMs) { usleep((waitMs - muteWaitMs) * 2 * 1000); } Loading Loading @@ -1309,6 +1317,16 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, outputDesc->changeRefCount(stream, -1); // store time at which the stream was stopped - see isStreamActive() if (outputDesc->mRefCount[stream] == 0) { // Automatically disable the remote submix input when output is stopped on a // re routing mix of type MIX_TYPE_RECORDERS if (audio_is_remote_submix_device(outputDesc->mDevice) && outputDesc->mPolicyMix != NULL && outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, outputDesc->mPolicyMix->mRegistrationId); } outputDesc->mStopTime[stream] = systemTime(); audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); // delay the device switch by twice the latency because stopOutput() is executed when Loading Loading @@ -1406,6 +1424,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, String8 address = String8(""); bool isSoundTrigger = false; audio_source_t halInputSource = attr->source; AudioMix *policyMix = NULL; if (attr->source == AUDIO_SOURCE_REMOTE_SUBMIX && strncmp(attr->tags, "addr=", strlen("addr=")) == 0) { Loading @@ -1416,13 +1435,22 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, ALOGW("getInputForAttr() no policy for address %s", address.string()); return BAD_VALUE; } if (mPolicyMixes[index]->mMix.mMixType != MIX_TYPE_PLAYERS) { ALOGW("getInputForAttr() bad policy mix type for address %s", address.string()); return BAD_VALUE; } policyMix = &mPolicyMixes[index]->mMix; } else { device = getDeviceForInputSource(attr->source, &address); device = getDeviceForInputSource(attr->source, &policyMix); if (device == AUDIO_DEVICE_NONE) { ALOGW("getInputForAttr() could not find device for source %d", attr->source); return BAD_VALUE; } if (policyMix != NULL) { address = policyMix->mRegistrationId; } else if (audio_is_remote_submix_device(device)) { address = String8("0"); } // adapt channel selection to input source switch (attr->source) { case AUDIO_SOURCE_VOICE_UPLINK: Loading Loading @@ -1507,8 +1535,9 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, inputDesc->mFormat = format; inputDesc->mChannelMask = channelMask; inputDesc->mDevice = device; inputDesc->mSessions.add(session, address); inputDesc->mSessions.add(session); inputDesc->mIsSoundTrigger = isSoundTrigger; inputDesc->mPolicyMix = policyMix; addInput(*input, inputDesc); mpClientInterface->onAudioPortListUpdate(); Loading @@ -1526,7 +1555,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, } sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); index = inputDesc->mSessions.indexOfKey(session); index = inputDesc->mSessions.indexOf(session); if (index < 0) { ALOGW("startInput() unknown session %d on input %d", session, input); return BAD_VALUE; Loading @@ -1544,8 +1573,8 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput); if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput); stopInput(activeInput, activeDesc->mSessions.keyAt(0)); releaseInput(activeInput, activeDesc->mSessions.keyAt(0)); stopInput(activeInput, activeDesc->mSessions.itemAt(0)); releaseInput(activeInput, activeDesc->mSessions.itemAt(0)); } else { ALOGE("startInput(%d) failed: other input %d already started", input, activeInput); return INVALID_OPERATION; Loading @@ -1559,12 +1588,21 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, } setInputDevice(input, getNewInputDevice(input), true /* force */); // Automatically enable the remote submix output when input is started. // automatically enable the remote submix output when input is started if not // used by a policy mix of type MIX_TYPE_RECORDERS // For remote submix (a virtual device), we open only one input per capture request. if (audio_is_remote_submix_device(inputDesc->mDevice)) { String8 address = String8(""); if (inputDesc->mPolicyMix == NULL) { address = String8("0"); } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { address = inputDesc->mPolicyMix->mRegistrationId; } if (address != "") { setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, inputDesc->mSessions.valueAt(index)); address); } } } Loading @@ -1585,7 +1623,7 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input, } sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); index = inputDesc->mSessions.indexOfKey(session); index = inputDesc->mSessions.indexOf(session); if (index < 0) { ALOGW("stopInput() unknown session %d on input %d", session, input); return BAD_VALUE; Loading @@ -1599,11 +1637,20 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input, inputDesc->mRefCount--; if (inputDesc->mRefCount == 0) { // automatically disable the remote submix output when input is stopped // automatically disable the remote submix output when input is stopped if not // used by a policy mix of type MIX_TYPE_RECORDERS if (audio_is_remote_submix_device(inputDesc->mDevice)) { String8 address = String8(""); if (inputDesc->mPolicyMix == NULL) { address = String8("0"); } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { address = inputDesc->mPolicyMix->mRegistrationId; } if (address != "") { setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, inputDesc->mSessions.valueAt(index)); address); } } resetInputDevice(input); Loading @@ -1627,12 +1674,12 @@ void AudioPolicyManager::releaseInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); ALOG_ASSERT(inputDesc != 0); index = inputDesc->mSessions.indexOfKey(session); index = inputDesc->mSessions.indexOf(session); if (index < 0) { ALOGW("releaseInput() unknown session %d on input %d", session, input); return; } inputDesc->mSessions.removeItem(session); inputDesc->mSessions.remove(session); if (inputDesc->mOpenRefCount == 0) { ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount); return; Loading Loading @@ -1961,10 +2008,9 @@ bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && outputDesc->isStreamActive(stream, inPastMs, sysTime)) { // only consider empty or "0" address to only qualify the screen mirroring case // as "remote playback" (vs rerouting when the output is going to a dynamic policy) if (outputDesc->mPolicyMixAddress == String8("") || outputDesc->mPolicyMixAddress == String8("0")) { // do not consider re routing (when the output is going to a dynamic policy) // as "remote playback" if (outputDesc->mPolicyMix == NULL) { return true; } } Loading Loading @@ -2046,9 +2092,15 @@ status_t AudioPolicyManager::registerPolicyMixes(Vector<AudioMix> mixes) sp<AudioPolicyMix> policyMix = new AudioPolicyMix(); policyMix->mMix = mixes[i]; mPolicyMixes.add(address, policyMix); if (mixes[i].mMixType == MIX_TYPE_PLAYERS) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.string()); } else { setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.string()); } } return NO_ERROR; } Loading Loading @@ -2080,9 +2132,13 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes) mPolicyMixes.removeItemsAt(index); if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.string()); } if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) Loading Loading @@ -3543,12 +3599,14 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de ssize_t index = mPolicyMixes.indexOfKey(address); if (index >= 0) { mPolicyMixes[index]->mOutput = desc; desc->mPolicyMix = &mPolicyMixes[index]->mMix; } else { ALOGE("checkOutputsForDevice() cannot find policy for address %s", address.string()); } } if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { // no duplicated output for direct outputs and // outputs used by dynamic policy mixes audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE; // set initial stream volume for device Loading Loading @@ -5014,7 +5072,7 @@ sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devi } audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource, String8 *address) AudioMix **policyMix) { uint32_t device = AUDIO_DEVICE_NONE; audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & Loading @@ -5030,8 +5088,8 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t input (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mPolicyMixes[i]->mMix.mCriteria[j].mRule && mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mSource != inputSource)) { if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { if (address != NULL) { *address = mPolicyMixes[i]->mMix.mRegistrationId; if (policyMix != NULL) { *policyMix = &mPolicyMixes[i]->mMix; } return AUDIO_DEVICE_IN_REMOTE_SUBMIX; } Loading Loading @@ -5127,9 +5185,6 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t input case AUDIO_SOURCE_REMOTE_SUBMIX: if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; if (address != NULL) { *address = "0"; } } break; case AUDIO_SOURCE_FM_TUNER: Loading Loading @@ -5571,8 +5626,7 @@ status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, ssize_t index = mOutputs.indexOfKey(output); if (index >= 0) { sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); if (outputDesc->mPolicyMixAddress != String8("") && outputDesc->mPolicyMixAddress != String8("0")) { if (outputDesc->mPolicyMix != NULL) { ALOGV("max gain when rerouting for output=%d", output); volume = 1.0f; } Loading Loading @@ -5761,7 +5815,7 @@ uint32_t AudioPolicyManager::getMaxEffectsMemory() AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( const sp<IOProfile>& profile) : mId(0), mIoHandle(0), mLatency(0), mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMixAddress(String8("")), mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) { Loading Loading @@ -5957,7 +6011,7 @@ status_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile) : mId(0), mIoHandle(0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0), mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false) { if (profile != NULL) { Loading services/audiopolicy/AudioPolicyManager.h +4 −5 Original line number Diff line number Diff line Loading @@ -497,7 +497,7 @@ protected: uint32_t mLatency; // audio_output_flags_t mFlags; // audio_devices_t mDevice; // current device this output is routed to String8 mPolicyMixAddress; // non empty or "0" when used by a dynamic policy AudioMix *mPolicyMix; // non NULL when used by a dynamic policy audio_patch_handle_t mPatchHandle; uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output nsecs_t mStopTime[AUDIO_STREAM_CNT]; Loading @@ -523,6 +523,7 @@ protected: audio_port_handle_t mId; audio_io_handle_t mIoHandle; // input handle audio_devices_t mDevice; // current device this input is routed to AudioMix *mPolicyMix; // non NULL when used by a dynamic policy audio_patch_handle_t mPatchHandle; uint32_t mRefCount; // number of AudioRecord clients using // this input Loading @@ -530,9 +531,7 @@ protected: audio_source_t mInputSource; // input source selected by application //(mediarecorder.h) const sp<IOProfile> mProfile; // I/O profile this output derives from // audio sessions attached to this input and the // corresponding device address DefaultKeyedVector<audio_session_t, String8> mSessions; SortedVector<audio_session_t> mSessions; // audio sessions attached to this input bool mIsSoundTrigger; // used by a soundtrigger capture virtual void toAudioPortConfig(struct audio_port_config *dstConfig, Loading Loading @@ -612,7 +611,7 @@ protected: // select input device corresponding to requested audio source virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource, String8 *address = NULL); AudioMix **policyMix = NULL); // return io handle of active input or 0 if no input is active // Only considers inputs from physical devices (e.g. main mic, headset mic) when Loading Loading
services/audiopolicy/AudioPolicyManager.cpp +97 −43 Original line number Diff line number Diff line Loading @@ -899,14 +899,13 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, mPolicyMixes[i]->mMix.mRegistrationId.string(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { desc = mPolicyMixes[i]->mOutput; break; } } if (desc != 0) { if (!audio_is_linear_pcm(format)) { return BAD_VALUE; } desc->mPolicyMixAddress = mPolicyMixes[i]->mMix.mRegistrationId; desc->mPolicyMix = &mPolicyMixes[i]->mMix; *stream = streamTypefromAttributesInt(&attributes); *output = desc->mIoHandle; ALOGV("getOutputForAttr() returns output %d", *output); Loading Loading @@ -1227,8 +1226,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, if (outputDesc->mRefCount[stream] == 1) { // starting an output being rerouted? audio_devices_t newDevice; if (outputDesc->mPolicyMixAddress != String8("") && outputDesc->mPolicyMixAddress != String8("0")) { if (outputDesc->mPolicyMix != NULL) { newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX; } else { newDevice = getNewOutputDevice(output, false /*fromCache*/); Loading Loading @@ -1275,6 +1273,16 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, // update the outputs if starting an output with a stream that can affect notification // routing handleNotificationRoutingForStream(stream); // Automatically enable the remote submix input when output is started on a re routing mix // of type MIX_TYPE_RECORDERS if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL && outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, outputDesc->mPolicyMix->mRegistrationId); } if (waitMs > muteWaitMs) { usleep((waitMs - muteWaitMs) * 2 * 1000); } Loading Loading @@ -1309,6 +1317,16 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, outputDesc->changeRefCount(stream, -1); // store time at which the stream was stopped - see isStreamActive() if (outputDesc->mRefCount[stream] == 0) { // Automatically disable the remote submix input when output is stopped on a // re routing mix of type MIX_TYPE_RECORDERS if (audio_is_remote_submix_device(outputDesc->mDevice) && outputDesc->mPolicyMix != NULL && outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, outputDesc->mPolicyMix->mRegistrationId); } outputDesc->mStopTime[stream] = systemTime(); audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); // delay the device switch by twice the latency because stopOutput() is executed when Loading Loading @@ -1406,6 +1424,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, String8 address = String8(""); bool isSoundTrigger = false; audio_source_t halInputSource = attr->source; AudioMix *policyMix = NULL; if (attr->source == AUDIO_SOURCE_REMOTE_SUBMIX && strncmp(attr->tags, "addr=", strlen("addr=")) == 0) { Loading @@ -1416,13 +1435,22 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, ALOGW("getInputForAttr() no policy for address %s", address.string()); return BAD_VALUE; } if (mPolicyMixes[index]->mMix.mMixType != MIX_TYPE_PLAYERS) { ALOGW("getInputForAttr() bad policy mix type for address %s", address.string()); return BAD_VALUE; } policyMix = &mPolicyMixes[index]->mMix; } else { device = getDeviceForInputSource(attr->source, &address); device = getDeviceForInputSource(attr->source, &policyMix); if (device == AUDIO_DEVICE_NONE) { ALOGW("getInputForAttr() could not find device for source %d", attr->source); return BAD_VALUE; } if (policyMix != NULL) { address = policyMix->mRegistrationId; } else if (audio_is_remote_submix_device(device)) { address = String8("0"); } // adapt channel selection to input source switch (attr->source) { case AUDIO_SOURCE_VOICE_UPLINK: Loading Loading @@ -1507,8 +1535,9 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, inputDesc->mFormat = format; inputDesc->mChannelMask = channelMask; inputDesc->mDevice = device; inputDesc->mSessions.add(session, address); inputDesc->mSessions.add(session); inputDesc->mIsSoundTrigger = isSoundTrigger; inputDesc->mPolicyMix = policyMix; addInput(*input, inputDesc); mpClientInterface->onAudioPortListUpdate(); Loading @@ -1526,7 +1555,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, } sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); index = inputDesc->mSessions.indexOfKey(session); index = inputDesc->mSessions.indexOf(session); if (index < 0) { ALOGW("startInput() unknown session %d on input %d", session, input); return BAD_VALUE; Loading @@ -1544,8 +1573,8 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput); if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) { ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput); stopInput(activeInput, activeDesc->mSessions.keyAt(0)); releaseInput(activeInput, activeDesc->mSessions.keyAt(0)); stopInput(activeInput, activeDesc->mSessions.itemAt(0)); releaseInput(activeInput, activeDesc->mSessions.itemAt(0)); } else { ALOGE("startInput(%d) failed: other input %d already started", input, activeInput); return INVALID_OPERATION; Loading @@ -1559,12 +1588,21 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, } setInputDevice(input, getNewInputDevice(input), true /* force */); // Automatically enable the remote submix output when input is started. // automatically enable the remote submix output when input is started if not // used by a policy mix of type MIX_TYPE_RECORDERS // For remote submix (a virtual device), we open only one input per capture request. if (audio_is_remote_submix_device(inputDesc->mDevice)) { String8 address = String8(""); if (inputDesc->mPolicyMix == NULL) { address = String8("0"); } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { address = inputDesc->mPolicyMix->mRegistrationId; } if (address != "") { setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, inputDesc->mSessions.valueAt(index)); address); } } } Loading @@ -1585,7 +1623,7 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input, } sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); index = inputDesc->mSessions.indexOfKey(session); index = inputDesc->mSessions.indexOf(session); if (index < 0) { ALOGW("stopInput() unknown session %d on input %d", session, input); return BAD_VALUE; Loading @@ -1599,11 +1637,20 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input, inputDesc->mRefCount--; if (inputDesc->mRefCount == 0) { // automatically disable the remote submix output when input is stopped // automatically disable the remote submix output when input is stopped if not // used by a policy mix of type MIX_TYPE_RECORDERS if (audio_is_remote_submix_device(inputDesc->mDevice)) { String8 address = String8(""); if (inputDesc->mPolicyMix == NULL) { address = String8("0"); } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { address = inputDesc->mPolicyMix->mRegistrationId; } if (address != "") { setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, inputDesc->mSessions.valueAt(index)); address); } } resetInputDevice(input); Loading @@ -1627,12 +1674,12 @@ void AudioPolicyManager::releaseInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index); ALOG_ASSERT(inputDesc != 0); index = inputDesc->mSessions.indexOfKey(session); index = inputDesc->mSessions.indexOf(session); if (index < 0) { ALOGW("releaseInput() unknown session %d on input %d", session, input); return; } inputDesc->mSessions.removeItem(session); inputDesc->mSessions.remove(session); if (inputDesc->mOpenRefCount == 0) { ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount); return; Loading Loading @@ -1961,10 +2008,9 @@ bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && outputDesc->isStreamActive(stream, inPastMs, sysTime)) { // only consider empty or "0" address to only qualify the screen mirroring case // as "remote playback" (vs rerouting when the output is going to a dynamic policy) if (outputDesc->mPolicyMixAddress == String8("") || outputDesc->mPolicyMixAddress == String8("0")) { // do not consider re routing (when the output is going to a dynamic policy) // as "remote playback" if (outputDesc->mPolicyMix == NULL) { return true; } } Loading Loading @@ -2046,9 +2092,15 @@ status_t AudioPolicyManager::registerPolicyMixes(Vector<AudioMix> mixes) sp<AudioPolicyMix> policyMix = new AudioPolicyMix(); policyMix->mMix = mixes[i]; mPolicyMixes.add(address, policyMix); if (mixes[i].mMixType == MIX_TYPE_PLAYERS) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.string()); } else { setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.string()); } } return NO_ERROR; } Loading Loading @@ -2080,9 +2132,13 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes) mPolicyMixes.removeItemsAt(index); if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { setDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.string()); } if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) Loading Loading @@ -3543,12 +3599,14 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de ssize_t index = mPolicyMixes.indexOfKey(address); if (index >= 0) { mPolicyMixes[index]->mOutput = desc; desc->mPolicyMix = &mPolicyMixes[index]->mMix; } else { ALOGE("checkOutputsForDevice() cannot find policy for address %s", address.string()); } } if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { // no duplicated output for direct outputs and // outputs used by dynamic policy mixes audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE; // set initial stream volume for device Loading Loading @@ -5014,7 +5072,7 @@ sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devi } audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource, String8 *address) AudioMix **policyMix) { uint32_t device = AUDIO_DEVICE_NONE; audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & Loading @@ -5030,8 +5088,8 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t input (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mPolicyMixes[i]->mMix.mCriteria[j].mRule && mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mSource != inputSource)) { if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { if (address != NULL) { *address = mPolicyMixes[i]->mMix.mRegistrationId; if (policyMix != NULL) { *policyMix = &mPolicyMixes[i]->mMix; } return AUDIO_DEVICE_IN_REMOTE_SUBMIX; } Loading Loading @@ -5127,9 +5185,6 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t input case AUDIO_SOURCE_REMOTE_SUBMIX: if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; if (address != NULL) { *address = "0"; } } break; case AUDIO_SOURCE_FM_TUNER: Loading Loading @@ -5571,8 +5626,7 @@ status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, ssize_t index = mOutputs.indexOfKey(output); if (index >= 0) { sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); if (outputDesc->mPolicyMixAddress != String8("") && outputDesc->mPolicyMixAddress != String8("0")) { if (outputDesc->mPolicyMix != NULL) { ALOGV("max gain when rerouting for output=%d", output); volume = 1.0f; } Loading Loading @@ -5761,7 +5815,7 @@ uint32_t AudioPolicyManager::getMaxEffectsMemory() AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor( const sp<IOProfile>& profile) : mId(0), mIoHandle(0), mLatency(0), mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMixAddress(String8("")), mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) { Loading Loading @@ -5957,7 +6011,7 @@ status_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd) AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile) : mId(0), mIoHandle(0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0), mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false) { if (profile != NULL) { Loading
services/audiopolicy/AudioPolicyManager.h +4 −5 Original line number Diff line number Diff line Loading @@ -497,7 +497,7 @@ protected: uint32_t mLatency; // audio_output_flags_t mFlags; // audio_devices_t mDevice; // current device this output is routed to String8 mPolicyMixAddress; // non empty or "0" when used by a dynamic policy AudioMix *mPolicyMix; // non NULL when used by a dynamic policy audio_patch_handle_t mPatchHandle; uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output nsecs_t mStopTime[AUDIO_STREAM_CNT]; Loading @@ -523,6 +523,7 @@ protected: audio_port_handle_t mId; audio_io_handle_t mIoHandle; // input handle audio_devices_t mDevice; // current device this input is routed to AudioMix *mPolicyMix; // non NULL when used by a dynamic policy audio_patch_handle_t mPatchHandle; uint32_t mRefCount; // number of AudioRecord clients using // this input Loading @@ -530,9 +531,7 @@ protected: audio_source_t mInputSource; // input source selected by application //(mediarecorder.h) const sp<IOProfile> mProfile; // I/O profile this output derives from // audio sessions attached to this input and the // corresponding device address DefaultKeyedVector<audio_session_t, String8> mSessions; SortedVector<audio_session_t> mSessions; // audio sessions attached to this input bool mIsSoundTrigger; // used by a soundtrigger capture virtual void toAudioPortConfig(struct audio_port_config *dstConfig, Loading Loading @@ -612,7 +611,7 @@ protected: // select input device corresponding to requested audio source virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource, String8 *address = NULL); AudioMix **policyMix = NULL); // return io handle of active input or 0 if no input is active // Only considers inputs from physical devices (e.g. main mic, headset mic) when Loading