Loading services/audiopolicy/engineconfigurable/src/Engine.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,8 @@ routing_strategy Engine::ManagerInterfaceImpl::getStrategyForUsage(audio_usage_t { const SwAudioOutputCollection &outputs = mPolicyEngine->mApmObserver->getOutputs(); //FIXME: getStrategyForUsage() should return STRATEGY_ACCESSIBILITY and getDeviceForStrategy() // should be implemented accordingly for STRATEGY_ACCESSIBILITY if (usage == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY && (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM))) { Loading services/audiopolicy/enginedefault/src/Engine.cpp +44 −21 Original line number Diff line number Diff line Loading @@ -195,18 +195,9 @@ routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream) routing_strategy Engine::getStrategyForUsage(audio_usage_t usage) { const SwAudioOutputCollection &outputs = mApmObserver->getOutputs(); // usage to strategy mapping switch (usage) { case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: if (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM)) { return STRATEGY_SONIFICATION; } if (isInCall()) { return STRATEGY_PHONE; } return STRATEGY_ACCESSIBILITY; case AUDIO_USAGE_MEDIA: Loading Loading @@ -245,6 +236,17 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const const SwAudioOutputCollection &outputs = mApmObserver->getOutputs(); return getDeviceForStrategyInt(strategy, (DeviceVector&)availableOutputDevices, availableInputDevices, outputs); } audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy, DeviceVector &availableOutputDevices, const DeviceVector &availableInputDevices, const SwAudioOutputCollection &outputs) const { uint32_t device = AUDIO_DEVICE_NONE; uint32_t availableOutputDevicesType = availableOutputDevices.types(); Loading @@ -260,14 +262,16 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall()) { device = getDeviceForStrategy(STRATEGY_SONIFICATION); device = getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); } else if (outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing on a remote device, use the the sonification behavior. // Note that we test this usecase before testing if media is playing because // the isStreamActive() method only informs about the activity of a stream, not // if it's for local playback. Note also that we use the same delay between both tests device = getDeviceForStrategy(STRATEGY_SONIFICATION); device = getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); //user "safe" speaker if available instead of normal speaker to avoid triggering //other acoustic safety mechanisms for notification if ((device & AUDIO_DEVICE_OUT_SPEAKER) && Loading @@ -275,12 +279,15 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE; device &= ~AUDIO_DEVICE_OUT_SPEAKER; } } else if (outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { } else if (outputs.isStreamActive( AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing (or has recently played), use the same device device = getDeviceForStrategy(STRATEGY_MEDIA); device = getDeviceForStrategyInt( STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs); } else { // when media is not playing anymore, fall back on the sonification behavior device = getDeviceForStrategy(STRATEGY_SONIFICATION); device = getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); //user "safe" speaker if available instead of normal speaker to avoid triggering //other acoustic safety mechanisms for notification if ((device & AUDIO_DEVICE_OUT_SPEAKER) && Loading @@ -294,7 +301,8 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const case STRATEGY_DTMF: if (!isInCall()) { // when off call, DTMF strategy follows the same rules as MEDIA strategy device = getDeviceForStrategy(STRATEGY_MEDIA); device = getDeviceForStrategyInt( STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs); break; } // when in call, DTMF and PHONE strategies follow the same rules Loading @@ -321,8 +329,8 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const availableOutputDevicesType = availPrimaryOutputDevices; } } // for phone strategy, we first consider the forced use and then the available devices by order // of priority // for phone strategy, we first consider the forced use and then the available devices by // order of priority switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { case AUDIO_POLICY_FORCE_BT_SCO: if (!isInCall() || strategy != STRATEGY_DTMF) { Loading Loading @@ -408,7 +416,8 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by // handleIncallSonification(). if (isInCall()) { device = getDeviceForStrategy(STRATEGY_PHONE); device = getDeviceForStrategyInt( STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); break; } // FALL THROUGH Loading @@ -429,7 +438,6 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const // The second device used for sonification is the same as the device used by media strategy // FALL THROUGH // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now case STRATEGY_ACCESSIBILITY: if (strategy == STRATEGY_ACCESSIBILITY) { // do not route accessibility prompts to a digital output currently configured with a Loading @@ -443,20 +451,35 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const availableOutputDevicesType = availableOutputDevices.types() & ~devices; } } availableOutputDevices = availableOutputDevices.getDevicesFromType(availableOutputDevicesType); if (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM)) { return getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); } if (isInCall()) { return getDeviceForStrategyInt( STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); } } // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA // FALL THROUGH // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now case STRATEGY_REROUTING: case STRATEGY_MEDIA: { uint32_t device2 = AUDIO_DEVICE_NONE; if (strategy != STRATEGY_SONIFICATION) { // no sonification on remote submix (e.g. WFD) if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; } } if (isInCall() && (strategy == STRATEGY_MEDIA)) { device = getDeviceForStrategy(STRATEGY_PHONE); device = getDeviceForStrategyInt( STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); break; } if ((device2 == AUDIO_DEVICE_NONE) && Loading services/audiopolicy/enginedefault/src/Engine.h +4 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,10 @@ private: routing_strategy getStrategyForStream(audio_stream_type_t stream); routing_strategy getStrategyForUsage(audio_usage_t usage); audio_devices_t getDeviceForStrategy(routing_strategy strategy) const; audio_devices_t getDeviceForStrategyInt(routing_strategy strategy, DeviceVector &availableOutputDevices, const DeviceVector &availableInputDevices, const SwAudioOutputCollection &outputs) const; audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const; audio_mode_t mPhoneState; /**< current phone state. */ Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +79 −60 Original line number Diff line number Diff line Loading @@ -1794,8 +1794,15 @@ void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, { ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); mVolumeCurves->initStreamVolume(stream, indexMin, indexMax); if (stream == AUDIO_STREAM_MUSIC) { mVolumeCurves->initStreamVolume(AUDIO_STREAM_ACCESSIBILITY, indexMin, indexMax); // initialize other private stream volumes which follow this one routing_strategy strategy = getStrategy(stream); for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax); } } Loading Loading @@ -1823,38 +1830,43 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, if (device == AUDIO_DEVICE_OUT_DEFAULT) { mVolumeCurves->clearCurrentVolumeIndex(stream); } mVolumeCurves->addCurrentVolumeIndex(stream, device, index); // update volume on all outputs whose current device is also selected by the same // strategy as the device specified by the caller audio_devices_t selectedDevices = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); // it is possible that the requested device is not selected by the strategy (e.g an explicit // audio patch is active causing getDevicesForStream() to return this device. We must make // sure that the device passed is part of the devices considered when applying volume below. selectedDevices |= device; //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE; if (stream == AUDIO_STREAM_MUSIC) { mVolumeCurves->addCurrentVolumeIndex(AUDIO_STREAM_ACCESSIBILITY, device, index); accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/); // update other private stream volumes which follow this one routing_strategy strategy = getStrategy(stream); for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index); } // update volume on all outputs whose current device is also selected by the same // strategy as the device specified by the caller status_t status = NO_ERROR; for (size_t i = 0; i < mOutputs.size(); i++) { sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i); audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device()); if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & selectedDevices) != 0)) { status_t volStatus = checkAndSetVolume(stream, index, desc, curDevice); for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, true /*fromCache*/); // it is possible that the requested device is not selected by the strategy // (e.g an explicit audio patch is active causing getDevicesForStream() // to return this device. We must make sure that the device passed is part of the // devices considered when applying volume below. curStreamDevice |= device; if (((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & curStreamDevice) != 0))) { status_t volStatus = checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice); if (volStatus != NO_ERROR) { status = volStatus; } } if ((accessibilityDevice != AUDIO_DEVICE_NONE) && ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0))) { status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY, index, desc, curDevice); } } return status; Loading Loading @@ -1957,7 +1969,17 @@ status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const { return mOutputs.isStreamActive(stream, inPastMs); bool active = false; routing_strategy strategy = getStrategy(stream); for (int curStream = 0; curStream < AUDIO_STREAM_CNT && !active; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs); } return active; } bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const Loading Loading @@ -2838,7 +2860,7 @@ status_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& disconnectAudioSource(sourceDesc); routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes); audio_stream_type_t stream = audio_attributes_to_stream_type(&sourceDesc->mAttributes); audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes); sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice; audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true); Loading Loading @@ -2971,7 +2993,7 @@ status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescripto } removeAudioPatch(sourceDesc->mPatchDesc->mHandle); audio_stream_type_t stream = audio_attributes_to_stream_type(&sourceDesc->mAttributes); audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes); sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote(); if (swOutputDesc != 0) { stopSource(swOutputDesc, stream, false); Loading Loading @@ -4170,10 +4192,10 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescr // use device for strategy phone // 3: the strategy for enforced audible is active but not enforced on the output: // use the device for strategy enforced audible // 4: the strategy accessibility is active on the output: // use device for strategy accessibility // 5: the strategy sonification is active on the output: // 4: the strategy sonification is active on the output: // use device for strategy sonification // 5: the strategy accessibility is active on the output: // use device for strategy accessibility // 6: the strategy "respectful" sonification is active on the output: // use device for strategy "respectful" sonification // 7: the strategy media is active on the output: Loading @@ -4190,10 +4212,10 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescr device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) { device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) { device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) { device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) { Loading Loading @@ -4229,6 +4251,13 @@ audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) return device; } bool AudioPolicyManager::strategiesMatchForvolume(routing_strategy strategy1, routing_strategy strategy2) { return ((strategy1 == strategy2) || ((strategy1 == STRATEGY_ACCESSIBILITY) && (strategy2 == STRATEGY_MEDIA)) || ((strategy1 == STRATEGY_MEDIA) && (strategy2 == STRATEGY_ACCESSIBILITY))); } uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) { return (uint32_t)getStrategy(stream); } Loading @@ -4240,16 +4269,22 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) { return AUDIO_DEVICE_NONE; } audio_devices_t devices; audio_devices_t devices = AUDIO_DEVICE_NONE; routing_strategy strategy = getStrategy(stream); devices = getDeviceForStrategy(strategy, true /*fromCache*/); SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs); for (int curStrategy = 0; curStrategy < NUM_STRATEGIES; curStrategy++) { if (!strategiesMatchForvolume(strategy, (routing_strategy)curStrategy)) { continue; } audio_devices_t curDevices = getDeviceForStrategy((routing_strategy)curStrategy, true /*fromCache*/); SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs); for (size_t i = 0; i < outputs.size(); i++) { sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); if (isStrategyActive(outputDesc, strategy)) { devices = outputDesc->device(); break; if (isStrategyActive(outputDesc, (routing_strategy)curStrategy)) { curDevices |= outputDesc->device(); } } devices |= curDevices; } /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it Loading Loading @@ -4361,15 +4396,8 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate // the device = the device from the descriptor in the RouteMap, and exit. for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) { sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex); routing_strategy strat = getStrategy(route->mStreamType); // Special case for accessibility strategy which must follow any strategy it is // currently remapped to bool strategyMatch = (strat == strategy) || ((strategy == STRATEGY_ACCESSIBILITY) && ((mEngine->getStrategyForUsage( AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY) == strat) || (strat == STRATEGY_MEDIA))); if (strategyMatch && route->isActive()) { routing_strategy routeStrategy = getStrategy(route->mStreamType); if ((routeStrategy == strategy) && route->isActive()) { return route->mDeviceDescriptor->type(); } } Loading Loading @@ -5007,15 +5035,6 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_ case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: return AUDIO_STREAM_MUSIC; case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: if (isStreamActive(AUDIO_STREAM_ALARM)) { return AUDIO_STREAM_ALARM; } if (isStreamActive(AUDIO_STREAM_RING)) { return AUDIO_STREAM_RING; } if (isInCall()) { return AUDIO_STREAM_VOICE_CALL; } return AUDIO_STREAM_ACCESSIBILITY; case AUDIO_USAGE_ASSISTANCE_SONIFICATION: return AUDIO_STREAM_SYSTEM; Loading services/audiopolicy/managerdefault/AudioPolicyManager.h +3 −0 Original line number Diff line number Diff line Loading @@ -506,6 +506,9 @@ protected: void clearAudioSources(uid_t uid); static bool strategiesMatchForvolume(routing_strategy strategy1, routing_strategy strategy2); uid_t mUidCached; AudioPolicyClientInterface *mpClientInterface; // audio policy client interface sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor Loading Loading
services/audiopolicy/engineconfigurable/src/Engine.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,8 @@ routing_strategy Engine::ManagerInterfaceImpl::getStrategyForUsage(audio_usage_t { const SwAudioOutputCollection &outputs = mPolicyEngine->mApmObserver->getOutputs(); //FIXME: getStrategyForUsage() should return STRATEGY_ACCESSIBILITY and getDeviceForStrategy() // should be implemented accordingly for STRATEGY_ACCESSIBILITY if (usage == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY && (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM))) { Loading
services/audiopolicy/enginedefault/src/Engine.cpp +44 −21 Original line number Diff line number Diff line Loading @@ -195,18 +195,9 @@ routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream) routing_strategy Engine::getStrategyForUsage(audio_usage_t usage) { const SwAudioOutputCollection &outputs = mApmObserver->getOutputs(); // usage to strategy mapping switch (usage) { case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: if (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM)) { return STRATEGY_SONIFICATION; } if (isInCall()) { return STRATEGY_PHONE; } return STRATEGY_ACCESSIBILITY; case AUDIO_USAGE_MEDIA: Loading Loading @@ -245,6 +236,17 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const const SwAudioOutputCollection &outputs = mApmObserver->getOutputs(); return getDeviceForStrategyInt(strategy, (DeviceVector&)availableOutputDevices, availableInputDevices, outputs); } audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy, DeviceVector &availableOutputDevices, const DeviceVector &availableInputDevices, const SwAudioOutputCollection &outputs) const { uint32_t device = AUDIO_DEVICE_NONE; uint32_t availableOutputDevicesType = availableOutputDevices.types(); Loading @@ -260,14 +262,16 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall()) { device = getDeviceForStrategy(STRATEGY_SONIFICATION); device = getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); } else if (outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing on a remote device, use the the sonification behavior. // Note that we test this usecase before testing if media is playing because // the isStreamActive() method only informs about the activity of a stream, not // if it's for local playback. Note also that we use the same delay between both tests device = getDeviceForStrategy(STRATEGY_SONIFICATION); device = getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); //user "safe" speaker if available instead of normal speaker to avoid triggering //other acoustic safety mechanisms for notification if ((device & AUDIO_DEVICE_OUT_SPEAKER) && Loading @@ -275,12 +279,15 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE; device &= ~AUDIO_DEVICE_OUT_SPEAKER; } } else if (outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { } else if (outputs.isStreamActive( AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing (or has recently played), use the same device device = getDeviceForStrategy(STRATEGY_MEDIA); device = getDeviceForStrategyInt( STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs); } else { // when media is not playing anymore, fall back on the sonification behavior device = getDeviceForStrategy(STRATEGY_SONIFICATION); device = getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); //user "safe" speaker if available instead of normal speaker to avoid triggering //other acoustic safety mechanisms for notification if ((device & AUDIO_DEVICE_OUT_SPEAKER) && Loading @@ -294,7 +301,8 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const case STRATEGY_DTMF: if (!isInCall()) { // when off call, DTMF strategy follows the same rules as MEDIA strategy device = getDeviceForStrategy(STRATEGY_MEDIA); device = getDeviceForStrategyInt( STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs); break; } // when in call, DTMF and PHONE strategies follow the same rules Loading @@ -321,8 +329,8 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const availableOutputDevicesType = availPrimaryOutputDevices; } } // for phone strategy, we first consider the forced use and then the available devices by order // of priority // for phone strategy, we first consider the forced use and then the available devices by // order of priority switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { case AUDIO_POLICY_FORCE_BT_SCO: if (!isInCall() || strategy != STRATEGY_DTMF) { Loading Loading @@ -408,7 +416,8 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by // handleIncallSonification(). if (isInCall()) { device = getDeviceForStrategy(STRATEGY_PHONE); device = getDeviceForStrategyInt( STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); break; } // FALL THROUGH Loading @@ -429,7 +438,6 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const // The second device used for sonification is the same as the device used by media strategy // FALL THROUGH // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now case STRATEGY_ACCESSIBILITY: if (strategy == STRATEGY_ACCESSIBILITY) { // do not route accessibility prompts to a digital output currently configured with a Loading @@ -443,20 +451,35 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const availableOutputDevicesType = availableOutputDevices.types() & ~devices; } } availableOutputDevices = availableOutputDevices.getDevicesFromType(availableOutputDevicesType); if (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM)) { return getDeviceForStrategyInt( STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); } if (isInCall()) { return getDeviceForStrategyInt( STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); } } // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA // FALL THROUGH // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now case STRATEGY_REROUTING: case STRATEGY_MEDIA: { uint32_t device2 = AUDIO_DEVICE_NONE; if (strategy != STRATEGY_SONIFICATION) { // no sonification on remote submix (e.g. WFD) if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; } } if (isInCall() && (strategy == STRATEGY_MEDIA)) { device = getDeviceForStrategy(STRATEGY_PHONE); device = getDeviceForStrategyInt( STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); break; } if ((device2 == AUDIO_DEVICE_NONE) && Loading
services/audiopolicy/enginedefault/src/Engine.h +4 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,10 @@ private: routing_strategy getStrategyForStream(audio_stream_type_t stream); routing_strategy getStrategyForUsage(audio_usage_t usage); audio_devices_t getDeviceForStrategy(routing_strategy strategy) const; audio_devices_t getDeviceForStrategyInt(routing_strategy strategy, DeviceVector &availableOutputDevices, const DeviceVector &availableInputDevices, const SwAudioOutputCollection &outputs) const; audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const; audio_mode_t mPhoneState; /**< current phone state. */ Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +79 −60 Original line number Diff line number Diff line Loading @@ -1794,8 +1794,15 @@ void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, { ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); mVolumeCurves->initStreamVolume(stream, indexMin, indexMax); if (stream == AUDIO_STREAM_MUSIC) { mVolumeCurves->initStreamVolume(AUDIO_STREAM_ACCESSIBILITY, indexMin, indexMax); // initialize other private stream volumes which follow this one routing_strategy strategy = getStrategy(stream); for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax); } } Loading Loading @@ -1823,38 +1830,43 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, if (device == AUDIO_DEVICE_OUT_DEFAULT) { mVolumeCurves->clearCurrentVolumeIndex(stream); } mVolumeCurves->addCurrentVolumeIndex(stream, device, index); // update volume on all outputs whose current device is also selected by the same // strategy as the device specified by the caller audio_devices_t selectedDevices = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); // it is possible that the requested device is not selected by the strategy (e.g an explicit // audio patch is active causing getDevicesForStream() to return this device. We must make // sure that the device passed is part of the devices considered when applying volume below. selectedDevices |= device; //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE; if (stream == AUDIO_STREAM_MUSIC) { mVolumeCurves->addCurrentVolumeIndex(AUDIO_STREAM_ACCESSIBILITY, device, index); accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/); // update other private stream volumes which follow this one routing_strategy strategy = getStrategy(stream); for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index); } // update volume on all outputs whose current device is also selected by the same // strategy as the device specified by the caller status_t status = NO_ERROR; for (size_t i = 0; i < mOutputs.size(); i++) { sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i); audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device()); if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & selectedDevices) != 0)) { status_t volStatus = checkAndSetVolume(stream, index, desc, curDevice); for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, true /*fromCache*/); // it is possible that the requested device is not selected by the strategy // (e.g an explicit audio patch is active causing getDevicesForStream() // to return this device. We must make sure that the device passed is part of the // devices considered when applying volume below. curStreamDevice |= device; if (((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & curStreamDevice) != 0))) { status_t volStatus = checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice); if (volStatus != NO_ERROR) { status = volStatus; } } if ((accessibilityDevice != AUDIO_DEVICE_NONE) && ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0))) { status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY, index, desc, curDevice); } } return status; Loading Loading @@ -1957,7 +1969,17 @@ status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const { return mOutputs.isStreamActive(stream, inPastMs); bool active = false; routing_strategy strategy = getStrategy(stream); for (int curStream = 0; curStream < AUDIO_STREAM_CNT && !active; curStream++) { routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream); if (!strategiesMatchForvolume(strategy, curStrategy)) { continue; } active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs); } return active; } bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const Loading Loading @@ -2838,7 +2860,7 @@ status_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& disconnectAudioSource(sourceDesc); routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes); audio_stream_type_t stream = audio_attributes_to_stream_type(&sourceDesc->mAttributes); audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes); sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice; audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true); Loading Loading @@ -2971,7 +2993,7 @@ status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescripto } removeAudioPatch(sourceDesc->mPatchDesc->mHandle); audio_stream_type_t stream = audio_attributes_to_stream_type(&sourceDesc->mAttributes); audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes); sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote(); if (swOutputDesc != 0) { stopSource(swOutputDesc, stream, false); Loading Loading @@ -4170,10 +4192,10 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescr // use device for strategy phone // 3: the strategy for enforced audible is active but not enforced on the output: // use the device for strategy enforced audible // 4: the strategy accessibility is active on the output: // use device for strategy accessibility // 5: the strategy sonification is active on the output: // 4: the strategy sonification is active on the output: // use device for strategy sonification // 5: the strategy accessibility is active on the output: // use device for strategy accessibility // 6: the strategy "respectful" sonification is active on the output: // use device for strategy "respectful" sonification // 7: the strategy media is active on the output: Loading @@ -4190,10 +4212,10 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescr device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) { device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) { device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) { device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) { Loading Loading @@ -4229,6 +4251,13 @@ audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input) return device; } bool AudioPolicyManager::strategiesMatchForvolume(routing_strategy strategy1, routing_strategy strategy2) { return ((strategy1 == strategy2) || ((strategy1 == STRATEGY_ACCESSIBILITY) && (strategy2 == STRATEGY_MEDIA)) || ((strategy1 == STRATEGY_MEDIA) && (strategy2 == STRATEGY_ACCESSIBILITY))); } uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) { return (uint32_t)getStrategy(stream); } Loading @@ -4240,16 +4269,22 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) { return AUDIO_DEVICE_NONE; } audio_devices_t devices; audio_devices_t devices = AUDIO_DEVICE_NONE; routing_strategy strategy = getStrategy(stream); devices = getDeviceForStrategy(strategy, true /*fromCache*/); SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs); for (int curStrategy = 0; curStrategy < NUM_STRATEGIES; curStrategy++) { if (!strategiesMatchForvolume(strategy, (routing_strategy)curStrategy)) { continue; } audio_devices_t curDevices = getDeviceForStrategy((routing_strategy)curStrategy, true /*fromCache*/); SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs); for (size_t i = 0; i < outputs.size(); i++) { sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]); if (isStrategyActive(outputDesc, strategy)) { devices = outputDesc->device(); break; if (isStrategyActive(outputDesc, (routing_strategy)curStrategy)) { curDevices |= outputDesc->device(); } } devices |= curDevices; } /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it Loading Loading @@ -4361,15 +4396,8 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate // the device = the device from the descriptor in the RouteMap, and exit. for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) { sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex); routing_strategy strat = getStrategy(route->mStreamType); // Special case for accessibility strategy which must follow any strategy it is // currently remapped to bool strategyMatch = (strat == strategy) || ((strategy == STRATEGY_ACCESSIBILITY) && ((mEngine->getStrategyForUsage( AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY) == strat) || (strat == STRATEGY_MEDIA))); if (strategyMatch && route->isActive()) { routing_strategy routeStrategy = getStrategy(route->mStreamType); if ((routeStrategy == strategy) && route->isActive()) { return route->mDeviceDescriptor->type(); } } Loading Loading @@ -5007,15 +5035,6 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_ case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: return AUDIO_STREAM_MUSIC; case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: if (isStreamActive(AUDIO_STREAM_ALARM)) { return AUDIO_STREAM_ALARM; } if (isStreamActive(AUDIO_STREAM_RING)) { return AUDIO_STREAM_RING; } if (isInCall()) { return AUDIO_STREAM_VOICE_CALL; } return AUDIO_STREAM_ACCESSIBILITY; case AUDIO_USAGE_ASSISTANCE_SONIFICATION: return AUDIO_STREAM_SYSTEM; Loading
services/audiopolicy/managerdefault/AudioPolicyManager.h +3 −0 Original line number Diff line number Diff line Loading @@ -506,6 +506,9 @@ protected: void clearAudioSources(uid_t uid); static bool strategiesMatchForvolume(routing_strategy strategy1, routing_strategy strategy2); uid_t mUidCached; AudioPolicyClientInterface *mpClientInterface; // audio policy client interface sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor Loading