summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy/managerdefault
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-05-22 10:32:38 -0700
committerEric Laurent <elaurent@google.com>2015-05-22 10:32:38 -0700
commit87ffa39d29d1803b48237888a9fbf3d5f2c60c21 (patch)
treecf0a01c080d17853881d3f9f1d0b72391667c530 /services/audiopolicy/managerdefault
parent4a95e69406aa2e9896d865962d6d947ebbdac6fc (diff)
downloadframeworks_av-87ffa39d29d1803b48237888a9fbf3d5f2c60c21.zip
frameworks_av-87ffa39d29d1803b48237888a9fbf3d5f2c60c21.tar.gz
frameworks_av-87ffa39d29d1803b48237888a9fbf3d5f2c60c21.tar.bz2
audio policy: add checks on primary output
Check if primary output has been initialized before using it. The primary output may not be initialized either due to HAL failure or on devices without telephony. Bug: 19573336. Change-Id: Id1fc3ed588268e1232b43d1e6235254d2f1a71d0
Diffstat (limited to 'services/audiopolicy/managerdefault')
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp69
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.h8
2 files changed, 47 insertions, 30 deletions
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index d1ee400..3f92011 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -171,7 +171,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
}
updateDevicesAndOutputs();
- if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) {
+ if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevice);
}
@@ -261,7 +261,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
closeAllInputs();
- if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) {
+ if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevice);
}
@@ -302,6 +302,9 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs
audio_patch_handle_t afPatchHandle;
DeviceVector deviceList;
+ if(!hasPrimaryOutput()) {
+ return;
+ }
audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
@@ -449,8 +452,6 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
checkOutputForAllStrategies();
updateDevicesAndOutputs();
- sp<SwAudioOutputDescriptor> hwOutputDesc = mPrimaryOutput;
-
int delayMs = 0;
if (isStateInCall(state)) {
nsecs_t sysTime = systemTime();
@@ -477,29 +478,31 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
}
}
- // Note that despite the fact that getNewOutputDevice() is called on the primary output,
- // the device returned is not necessarily reachable via this output
- audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
- // force routing command to audio hardware when ending call
- // even if no device change is needed
- if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
- rxDevice = hwOutputDesc->device();
- }
-
- if (state == AUDIO_MODE_IN_CALL) {
- updateCallRouting(rxDevice, delayMs);
- } else if (oldState == AUDIO_MODE_IN_CALL) {
- if (mCallRxPatch != 0) {
- mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
- mCallRxPatch.clear();
+ if (hasPrimaryOutput()) {
+ // Note that despite the fact that getNewOutputDevice() is called on the primary output,
+ // the device returned is not necessarily reachable via this output
+ audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+ // force routing command to audio hardware when ending call
+ // even if no device change is needed
+ if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
+ rxDevice = mPrimaryOutput->device();
}
- if (mCallTxPatch != 0) {
- mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
- mCallTxPatch.clear();
+
+ if (state == AUDIO_MODE_IN_CALL) {
+ updateCallRouting(rxDevice, delayMs);
+ } else if (oldState == AUDIO_MODE_IN_CALL) {
+ if (mCallRxPatch != 0) {
+ mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
+ mCallRxPatch.clear();
+ }
+ if (mCallTxPatch != 0) {
+ mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
+ mCallTxPatch.clear();
+ }
+ setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
+ } else {
+ setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
}
- setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
- } else {
- setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
}
// if entering in call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
@@ -543,7 +546,7 @@ void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
checkA2dpSuspend();
checkOutputForAllStrategies();
updateDevicesAndOutputs();
- if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) {
+ if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
updateCallRouting(newDevice);
}
@@ -1226,7 +1229,7 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
// If effects where present on the output, audioflinger moved them to the primary
// output by default: move them back to the appropriate output.
audio_io_handle_t dstOutput = getOutputForEffect();
- if (dstOutput != mPrimaryOutput->mIoHandle) {
+ if (hasPrimaryOutput() && dstOutput != mPrimaryOutput->mIoHandle) {
mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
mPrimaryOutput->mIoHandle, dstOutput);
}
@@ -1934,7 +1937,8 @@ status_t AudioPolicyManager::dump(int fd)
snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
result.append(buffer);
- snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput->mIoHandle);
+ snprintf(buffer, SIZE, " Primary Output: %d\n",
+ hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
result.append(buffer);
snprintf(buffer, SIZE, " Phone state: %d\n", mEngine->getPhoneState());
result.append(buffer);
@@ -2896,7 +2900,7 @@ AudioPolicyManager::~AudioPolicyManager()
status_t AudioPolicyManager::initCheck()
{
- return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR;
+ return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
}
#ifdef AUDIO_POLICY_TEST
@@ -3271,7 +3275,8 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de
policyMix->setOutput(desc);
desc->mPolicyMix = policyMix->getMix();
- } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
+ } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
+ hasPrimaryOutput()) {
// no duplicated output for direct outputs and
// outputs used by dynamic policy mixes
audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
@@ -4600,6 +4605,10 @@ void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
bool starting, bool stateChange)
{
+ if(!hasPrimaryOutput()) {
+ return;
+ }
+
// if the stream pertains to sonification strategy and we are in call we must
// mute the stream if it is low visibility. If it is high visibility, we must play a tone
// in the device used for phone strategy and play the tone if the selected device does not
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index ea16864..f9d1198 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -553,10 +553,16 @@ protected:
audio_devices_t availablePrimaryOutputDevices() const
{
+ if (!hasPrimaryOutput()) {
+ return AUDIO_DEVICE_NONE;
+ }
return mPrimaryOutput->supportedDevices() & mAvailableOutputDevices.types();
}
audio_devices_t availablePrimaryInputDevices() const
{
+ if (!hasPrimaryOutput()) {
+ return AUDIO_DEVICE_NONE;
+ }
return mAvailableInputDevices.getDevicesFromHwModule(mPrimaryOutput->getModuleHandle());
}
@@ -576,6 +582,8 @@ protected:
void clearSessionRoutes(uid_t uid);
void checkStrategyRoute(routing_strategy strategy, audio_io_handle_t ouptutToSkip);
+ status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
+
uid_t mUidCached;
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
sp<SwAudioOutputDescriptor> mPrimaryOutput; // primary output descriptor