Loading policy_hal/AudioPolicyManager.cpp +0 −187 Original line number Diff line number Diff line Loading @@ -391,193 +391,6 @@ void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, AudioSystem:: } status_t AudioPolicyManager::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session) { ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); ssize_t index = mOutputs.indexOfKey(output); if (index < 0) { ALOGW("startOutput() unknow output %d", output); return BAD_VALUE; } 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 // necessary for a correct control of hardware output routing by startOutput() and stopOutput() outputDesc->changeRefCount(stream, 1); if (outputDesc->mRefCount[stream] == 1) { audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); routing_strategy strategy = getStrategy(stream); bool shouldWait = (strategy == STRATEGY_SONIFICATION) || (strategy == STRATEGY_SONIFICATION_RESPECTFUL); uint32_t waitMs = 0; bool force = false; for (size_t i = 0; i < mOutputs.size(); i++) { 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. // In this case, the audio HAL must receive the new device selection so that it can // change the device currently selected by the other active output. if (outputDesc->sharesHwModuleWith(desc) && desc->device() != newDevice) { force = true; } // wait for audio on other active outputs to be presented when starting // a notification so that audio focus effect can propagate. uint32_t latency = desc->latency(); if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { waitMs = latency; } } } uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); // handle special case for sonification while in call if (isInCall()) { handleIncallSonification(stream, true, false); } // apply volume rules for current stream and device if necessary checkAndSetVolume(stream, mStreams[stream].getVolumeIndex(newDevice), output, newDevice); // update the outputs if starting an output with a stream that can affect notification // routing handleNotificationRoutingForStream(stream); if (waitMs > muteWaitMs) { usleep((waitMs - muteWaitMs) * 2 * 1000); } } #ifdef DOLBY_UDC // It is observed that in some use-cases where both outputs are present eg. bluetooth and headphone, // the output for particular stream type is decided in this routine. Hence we must call // getDeviceForStrategy in order to get the current active output for this stream type and update // the dolby system property. if (stream == AudioSystem::MUSIC) { audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AudioSystem::MUSIC), true); DolbySystemProperty::set(audioOutputDevice); } #endif // DOLBY_END return NO_ERROR; } status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session) { ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); ssize_t index = mOutputs.indexOfKey(output); if (index < 0) { ALOGW("stopOutput() unknow output %d", output); return BAD_VALUE; } AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); // handle special case for sonification while in call if (isInCall()) { handleIncallSonification(stream, false, false); } if (outputDesc->mRefCount[stream] > 0) { // decrement usage count of this stream on the output outputDesc->changeRefCount(stream, -1); // store time at which the stream was stopped - see isStreamActive() if (outputDesc->mRefCount[stream] == 0) { outputDesc->mStopTime[stream] = systemTime(); audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); // delay the device switch by twice the latency because stopOutput() is executed when // the track stop() command is received and at that time the audio track buffer can // still contain data that needs to be drained. The latency only covers the audio HAL // and kernel buffers. Also the latency does not always include additional delay in the // audio path (audio DSP, CODEC ...) setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); // force restoring the device selection on other active outputs if it differs from the // 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); if (curOutput != output && desc->isActive() && outputDesc->sharesHwModuleWith(desc) && (newDevice != desc->device())) { setOutputDevice(curOutput, getNewDevice(curOutput, false /*fromCache*/), true, outputDesc->mLatency*2); } } // update the outputs if stopping one with a stream that can affect notification routing handleNotificationRoutingForStream(stream); } return NO_ERROR; } else { ALOGW("stopOutput() refcount is already 0 for output %d", output); return INVALID_OPERATION; } } audio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache) { audio_devices_t device = AUDIO_DEVICE_NONE; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); AudioOutputDescriptor *primaryOutputDesc = mOutputs.valueFor(mPrimaryOutput); // check the following by order of priority to request a routing change if necessary: // 1: the strategy enforced audible is active on the output: // use device for strategy enforced audible // 2: we are in call or the strategy phone is active on the output: // use device for strategy phone // 3: the strategy sonification is active on the output: // use device for strategy sonification // 4: the strategy "respectful" sonification is active on the output: // use device for strategy "respectful" sonification // 5: the strategy media is active on the output: // use device for strategy media // 6: the strategy DTMF is active on the output: // use device for strategy DTMF if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); } else if (isInCall() || outputDesc->isStrategyActive(STRATEGY_PHONE)) { device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)|| (primaryOutputDesc->isStrategyActive(STRATEGY_SONIFICATION)&& !primaryOutputDesc->isStrategyActive(STRATEGY_MEDIA))){ device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); } ALOGV("getNewDevice() selected device %x", device); return device; } //private function, no changes from AudioPolicyManagerBase void AudioPolicyManager::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { switch(stream) { case AudioSystem::MUSIC: checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); updateDevicesAndOutputs(); break; default: break; } } audio_io_handle_t AudioPolicyManager::getInput(int inputSource, uint32_t samplingRate, uint32_t format, Loading policy_hal/AudioPolicyManager.h +0 −10 Original line number Diff line number Diff line Loading @@ -61,12 +61,6 @@ public: virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo); virtual void setPhoneState(int state); virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session = 0); virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session = 0); protected: // return the strategy corresponding to a given stream type static routing_strategy getStrategy(AudioSystem::stream_type stream); Loading Loading @@ -94,7 +88,6 @@ protected: // check that volume change is permitted, compute and send new volume to audio hardware status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache); // returns the category the device belongs to with regard to volume curve management static device_category getDeviceCategory(audio_devices_t device); Loading @@ -106,10 +99,7 @@ protected: //parameter indicates if HDMI plug in/out detected bool mHdmiAudioEvent; private: void handleNotificationRoutingForStream(AudioSystem::stream_type stream); // Used for voip + voice concurrency usecase int mPrevPhoneState; Loading Loading
policy_hal/AudioPolicyManager.cpp +0 −187 Original line number Diff line number Diff line Loading @@ -391,193 +391,6 @@ void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, AudioSystem:: } status_t AudioPolicyManager::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session) { ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session); ssize_t index = mOutputs.indexOfKey(output); if (index < 0) { ALOGW("startOutput() unknow output %d", output); return BAD_VALUE; } 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 // necessary for a correct control of hardware output routing by startOutput() and stopOutput() outputDesc->changeRefCount(stream, 1); if (outputDesc->mRefCount[stream] == 1) { audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); routing_strategy strategy = getStrategy(stream); bool shouldWait = (strategy == STRATEGY_SONIFICATION) || (strategy == STRATEGY_SONIFICATION_RESPECTFUL); uint32_t waitMs = 0; bool force = false; for (size_t i = 0; i < mOutputs.size(); i++) { 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. // In this case, the audio HAL must receive the new device selection so that it can // change the device currently selected by the other active output. if (outputDesc->sharesHwModuleWith(desc) && desc->device() != newDevice) { force = true; } // wait for audio on other active outputs to be presented when starting // a notification so that audio focus effect can propagate. uint32_t latency = desc->latency(); if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) { waitMs = latency; } } } uint32_t muteWaitMs = setOutputDevice(output, newDevice, force); // handle special case for sonification while in call if (isInCall()) { handleIncallSonification(stream, true, false); } // apply volume rules for current stream and device if necessary checkAndSetVolume(stream, mStreams[stream].getVolumeIndex(newDevice), output, newDevice); // update the outputs if starting an output with a stream that can affect notification // routing handleNotificationRoutingForStream(stream); if (waitMs > muteWaitMs) { usleep((waitMs - muteWaitMs) * 2 * 1000); } } #ifdef DOLBY_UDC // It is observed that in some use-cases where both outputs are present eg. bluetooth and headphone, // the output for particular stream type is decided in this routine. Hence we must call // getDeviceForStrategy in order to get the current active output for this stream type and update // the dolby system property. if (stream == AudioSystem::MUSIC) { audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AudioSystem::MUSIC), true); DolbySystemProperty::set(audioOutputDevice); } #endif // DOLBY_END return NO_ERROR; } status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session) { ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session); ssize_t index = mOutputs.indexOfKey(output); if (index < 0) { ALOGW("stopOutput() unknow output %d", output); return BAD_VALUE; } AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); // handle special case for sonification while in call if (isInCall()) { handleIncallSonification(stream, false, false); } if (outputDesc->mRefCount[stream] > 0) { // decrement usage count of this stream on the output outputDesc->changeRefCount(stream, -1); // store time at which the stream was stopped - see isStreamActive() if (outputDesc->mRefCount[stream] == 0) { outputDesc->mStopTime[stream] = systemTime(); audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); // delay the device switch by twice the latency because stopOutput() is executed when // the track stop() command is received and at that time the audio track buffer can // still contain data that needs to be drained. The latency only covers the audio HAL // and kernel buffers. Also the latency does not always include additional delay in the // audio path (audio DSP, CODEC ...) setOutputDevice(output, newDevice, false, outputDesc->mLatency*2); // force restoring the device selection on other active outputs if it differs from the // 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); if (curOutput != output && desc->isActive() && outputDesc->sharesHwModuleWith(desc) && (newDevice != desc->device())) { setOutputDevice(curOutput, getNewDevice(curOutput, false /*fromCache*/), true, outputDesc->mLatency*2); } } // update the outputs if stopping one with a stream that can affect notification routing handleNotificationRoutingForStream(stream); } return NO_ERROR; } else { ALOGW("stopOutput() refcount is already 0 for output %d", output); return INVALID_OPERATION; } } audio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache) { audio_devices_t device = AUDIO_DEVICE_NONE; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); AudioOutputDescriptor *primaryOutputDesc = mOutputs.valueFor(mPrimaryOutput); // check the following by order of priority to request a routing change if necessary: // 1: the strategy enforced audible is active on the output: // use device for strategy enforced audible // 2: we are in call or the strategy phone is active on the output: // use device for strategy phone // 3: the strategy sonification is active on the output: // use device for strategy sonification // 4: the strategy "respectful" sonification is active on the output: // use device for strategy "respectful" sonification // 5: the strategy media is active on the output: // use device for strategy media // 6: the strategy DTMF is active on the output: // use device for strategy DTMF if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); } else if (isInCall() || outputDesc->isStrategyActive(STRATEGY_PHONE)) { device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)|| (primaryOutputDesc->isStrategyActive(STRATEGY_SONIFICATION)&& !primaryOutputDesc->isStrategyActive(STRATEGY_MEDIA))){ device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); } ALOGV("getNewDevice() selected device %x", device); return device; } //private function, no changes from AudioPolicyManagerBase void AudioPolicyManager::handleNotificationRoutingForStream(AudioSystem::stream_type stream) { switch(stream) { case AudioSystem::MUSIC: checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); updateDevicesAndOutputs(); break; default: break; } } audio_io_handle_t AudioPolicyManager::getInput(int inputSource, uint32_t samplingRate, uint32_t format, Loading
policy_hal/AudioPolicyManager.h +0 −10 Original line number Diff line number Diff line Loading @@ -61,12 +61,6 @@ public: virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo); virtual void setPhoneState(int state); virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session = 0); virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session = 0); protected: // return the strategy corresponding to a given stream type static routing_strategy getStrategy(AudioSystem::stream_type stream); Loading Loading @@ -94,7 +88,6 @@ protected: // check that volume change is permitted, compute and send new volume to audio hardware status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false); audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache); // returns the category the device belongs to with regard to volume curve management static device_category getDeviceCategory(audio_devices_t device); Loading @@ -106,10 +99,7 @@ protected: //parameter indicates if HDMI plug in/out detected bool mHdmiAudioEvent; private: void handleNotificationRoutingForStream(AudioSystem::stream_type stream); // Used for voip + voice concurrency usecase int mPrevPhoneState; Loading