diff options
-rw-r--r-- | audio/A2dpAudioInterface.cpp | 4 | ||||
-rw-r--r-- | audio/AudioPolicyManagerBase.cpp | 358 | ||||
-rw-r--r-- | audio/audio_hw_hal.cpp | 155 | ||||
-rw-r--r-- | audio/audio_policy_hal.cpp | 12 | ||||
-rw-r--r-- | include/hardware_legacy/AudioPolicyInterface.h | 8 | ||||
-rw-r--r-- | include/hardware_legacy/AudioPolicyManagerBase.h | 33 | ||||
-rw-r--r-- | include/hardware_legacy/AudioSystemLegacy.h | 13 |
7 files changed, 368 insertions, 215 deletions
diff --git a/audio/A2dpAudioInterface.cpp b/audio/A2dpAudioInterface.cpp index cc435bd..9359ec3 100644 --- a/audio/A2dpAudioInterface.cpp +++ b/audio/A2dpAudioInterface.cpp @@ -63,7 +63,7 @@ status_t A2dpAudioInterface::initCheck() AudioStreamOut* A2dpAudioInterface::openOutputStream( uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) { - if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices)) { + if (!audio_is_a2dp_device(devices)) { ALOGV("A2dpAudioInterface::openOutputStream() open HW device: %x", devices); return mHardwareInterface->openOutputStream(devices, format, channels, sampleRate, status); } @@ -398,7 +398,7 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& ke } key = AudioParameter::keyRouting; if (param.getInt(key, device) == NO_ERROR) { - if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device)) { + if (audio_is_a2dp_device(device)) { mDevice = device; status = NO_ERROR; } else { diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index cce60b5..9625491 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -24,6 +24,10 @@ #define ALOGVV(a...) do { } while(0) #endif +// A device mask for all audio input devices that are considered "virtual" when evaluating +// active inputs in getActiveInput() +#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX + #include <utils/Log.h> #include <hardware_legacy/AudioPolicyManagerBase.h> #include <hardware/audio_effect.h> @@ -38,7 +42,7 @@ namespace android_audio_legacy { // ---------------------------------------------------------------------------- -status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device, +status_t AudioPolicyManagerBase::setDeviceConnectionState(audio_devices_t device, AudioSystem::device_connection_state state, const char *device_address) { @@ -47,7 +51,7 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); // connect/disconnect only 1 device at a time - if (AudioSystem::popCount(device) != 1) return BAD_VALUE; + if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { ALOGE("setDeviceConnectionState() invalid address: %s", device_address); @@ -55,17 +59,24 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev } // handle output devices - if (AudioSystem::isOutputDevice(device)) { + if (audio_is_output_device(device)) { - if (!mHasA2dp && AudioSystem::isA2dpDevice(device)) { - ALOGE("setDeviceConnectionState() invalid device: %x", device); + if (!mHasA2dp && audio_is_a2dp_device(device)) { + ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device); + return BAD_VALUE; + } + if (!mHasUsb && audio_is_usb_device(device)) { + ALOGE("setDeviceConnectionState() invalid USB audio device: %x", device); return BAD_VALUE; } - if (!mHasUsb && audio_is_usb_device((audio_devices_t)device)) { - ALOGE("setDeviceConnectionState() invalid device: %x", device); + if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) { + ALOGE("setDeviceConnectionState() invalid remote submix audio device: %x", device); return BAD_VALUE; } + // save a copy of the opened output descriptors before any output is opened or closed + // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies() + mPreviousOutputs = mOutputs; switch (state) { // handle output device connection @@ -76,7 +87,7 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev } ALOGV("setDeviceConnectionState() connecting device %x", device); - if (checkOutputsForDevice((audio_devices_t)device, state, outputs) != NO_ERROR) { + if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) { return INVALID_OPERATION; } ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs", @@ -86,21 +97,23 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev if (!outputs.isEmpty()) { String8 paramStr; - if (mHasA2dp && AudioSystem::isA2dpDevice(device)) { + if (mHasA2dp && audio_is_a2dp_device(device)) { // handle A2DP device connection AudioParameter param; param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address)); paramStr = param.toString(); mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); mA2dpSuspended = false; - } else if (AudioSystem::isBluetoothScoDevice(device)) { + } else if (audio_is_bluetooth_sco_device(device)) { // handle SCO device connection mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); - } else if (mHasUsb && audio_is_usb_device((audio_devices_t)device)) { + } else if (mHasUsb && audio_is_usb_device(device)) { // handle USB device connection mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); paramStr = mUsbCardAndDevice; } + // not currently handling multiple simultaneous submixes: ignoring remote submix + // case and address if (!paramStr.isEmpty()) { for (size_t i = 0; i < outputs.size(); i++) { mpClientInterface->setParameters(outputs[i], paramStr); @@ -119,18 +132,20 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev // remove device from available output devices mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); - checkOutputsForDevice((audio_devices_t)device, state, outputs); - if (mHasA2dp && AudioSystem::isA2dpDevice(device)) { + checkOutputsForDevice(device, state, outputs); + if (mHasA2dp && audio_is_a2dp_device(device)) { // handle A2DP device disconnection mA2dpDeviceAddress = ""; mA2dpSuspended = false; - } else if (AudioSystem::isBluetoothScoDevice(device)) { + } else if (audio_is_bluetooth_sco_device(device)) { // handle SCO device disconnection mScoDeviceAddress = ""; - } else if (mHasUsb && audio_is_usb_device((audio_devices_t)device)) { + } else if (mHasUsb && audio_is_usb_device(device)) { // handle USB device disconnection mUsbCardAndDevice = ""; } + // not currently handling multiple simultaneous submixes: ignoring remote submix + // case and address } break; default: @@ -152,23 +167,23 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev } } - updateDeviceForStrategy(); + updateDevicesAndOutputs(); for (size_t i = 0; i < mOutputs.size(); i++) { setOutputDevice(mOutputs.keyAt(i), getNewDevice(mOutputs.keyAt(i), true /*fromCache*/)); } - if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) { - device = AudioSystem::DEVICE_IN_WIRED_HEADSET; - } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO || - device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET || - device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { - device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; + if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) { + device = AUDIO_DEVICE_IN_WIRED_HEADSET; + } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO || + device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET || + device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { + device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; } else { return NO_ERROR; } } // handle input devices - if (AudioSystem::isInputDevice(device)) { + if (audio_is_input_device(device)) { switch (state) { @@ -178,7 +193,7 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev ALOGW("setDeviceConnectionState() device already connected: %d", device); return INVALID_OPERATION; } - mAvailableInputDevices = (audio_devices_t)(mAvailableInputDevices | device); + mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN); } break; @@ -200,7 +215,7 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev if (activeInput != 0) { AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); - if ((newDevice != 0) && (newDevice != inputDesc->mDevice)) { + if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d", inputDesc->mDevice, newDevice, activeInput); inputDesc->mDevice = newDevice; @@ -217,29 +232,32 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev return BAD_VALUE; } -AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device, +AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(audio_devices_t device, const char *device_address) { AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; String8 address = String8(device_address); - if (AudioSystem::isOutputDevice(device)) { + if (audio_is_output_device(device)) { if (device & mAvailableOutputDevices) { - if (AudioSystem::isA2dpDevice(device) && + if (audio_is_a2dp_device(device) && (!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { return state; } - if (AudioSystem::isBluetoothScoDevice(device) && + if (audio_is_bluetooth_sco_device(device) && address != "" && mScoDeviceAddress != address) { return state; } - if (audio_is_usb_device((audio_devices_t)device) && + if (audio_is_usb_device(device) && (!mHasUsb || (address != "" && mUsbCardAndDevice != address))) { - ALOGE("setDeviceConnectionState() invalid device: %x", device); + ALOGE("getDeviceConnectionState() invalid device: %x", device); + return state; + } + if (audio_is_remote_submix_device((audio_devices_t)device) && !mHasRemoteSubmix) { return state; } state = AudioSystem::DEVICE_STATE_AVAILABLE; } - } else if (AudioSystem::isInputDevice(device)) { + } else if (audio_is_input_device(device)) { if (device & mAvailableInputDevices) { state = AudioSystem::DEVICE_STATE_AVAILABLE; } @@ -251,7 +269,7 @@ AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnection void AudioPolicyManagerBase::setPhoneState(int state) { ALOGV("setPhoneState() state %d", state); - audio_devices_t newDevice = (audio_devices_t)0; + audio_devices_t newDevice = AUDIO_DEVICE_NONE; if (state < 0 || state >= AudioSystem::NUM_MODES) { ALOGW("setPhoneState() invalid state %d", state); return; @@ -298,13 +316,13 @@ void AudioPolicyManagerBase::setPhoneState(int state) newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); checkA2dpSuspend(); checkOutputForAllStrategies(); - updateDeviceForStrategy(); + updateDevicesAndOutputs(); AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); // force routing command to audio hardware when ending call // even if no device change is needed - if (isStateInCall(oldState) && newDevice == 0) { + if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { newDevice = hwOutputDesc->device(); } @@ -366,7 +384,8 @@ void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSyst config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_ANALOG_DOCK && config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE && - config != AudioSystem::FORCE_NO_BT_A2DP) { + config != AudioSystem::FORCE_NO_BT_A2DP && + config != AudioSystem::FORCE_REMOTE_SUBMIX) { ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); return; } @@ -399,12 +418,12 @@ void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSyst // check for device and output changes triggered by new force usage checkA2dpSuspend(); checkOutputForAllStrategies(); - updateDeviceForStrategy(); + updateDevicesAndOutputs(); for (size_t i = 0; i < mOutputs.size(); i++) { audio_io_handle_t output = mOutputs.keyAt(i); audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/); - setOutputDevice(output, newDevice, (newDevice != 0)); - if (forceVolumeReeval && (newDevice != 0)) { + setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE)); + if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) { applyStreamVolumes(output, newDevice, 0, true); } } @@ -413,7 +432,7 @@ void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSyst if (activeInput != 0) { AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); - if ((newDevice != 0) && (newDevice != inputDesc->mDevice)) { + if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { ALOGV("setForceUse() changing device from %x to %x for input %d", inputDesc->mDevice, newDevice, activeInput); inputDesc->mDevice = newDevice; @@ -567,7 +586,7 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str // get which output is suitable for the specified stream. The actual routing change will happen // when startOutput() will be called - SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device); + SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs); output = selectOutput(outputs, flags); @@ -644,7 +663,6 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, outputDesc->changeRefCount(stream, 1); if (outputDesc->mRefCount[stream] == 1) { - audio_devices_t prevDevice = outputDesc->device(); audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/); routing_strategy strategy = getStrategy(stream); bool shouldWait = (strategy == STRATEGY_SONIFICATION) || @@ -678,7 +696,7 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, // apply volume rules for current stream and device if necessary checkAndSetVolume(stream, - mStreams[stream].getVolumeIndex((audio_devices_t)newDevice), + mStreams[stream].getVolumeIndex(newDevice), output, newDevice); @@ -793,7 +811,7 @@ audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource, ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x", inputSource, samplingRate, format, channelMask, acoustics); - if (device == 0) { + if (device == AUDIO_DEVICE_NONE) { ALOGW("getInput() could not find device for inputSource %d", inputSource); return 0; } @@ -971,7 +989,7 @@ status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type s status_t status = NO_ERROR; for (size_t i = 0; i < mOutputs.size(); i++) { audio_devices_t curDevice = - getDeviceForVolume((audio_devices_t)mOutputs.valueAt(i)->device()); + getDeviceForVolume(mOutputs.valueAt(i)->device()); if (device == curDevice) { status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice); if (volStatus != NO_ERROR) { @@ -995,7 +1013,7 @@ status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type s // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to // the strategy the stream belongs to. if (device == AUDIO_DEVICE_OUT_DEFAULT) { - device = (audio_devices_t)getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); + device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); } device = getDeviceForVolume(device); @@ -1004,14 +1022,14 @@ status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type s return NO_ERROR; } -audio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(effect_descriptor_t *desc) +audio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(const effect_descriptor_t *desc) { ALOGV("getOutputForEffect()"); // apply simple rule where global effects are attached to the same output as MUSIC streams routing_strategy strategy = getStrategy(AudioSystem::MUSIC); audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); - SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device); + SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs); int outIdx = 0; for (size_t i = 0; i < dstOutputs.size(); i++) { AudioOutputDescriptor *desc = mOutputs.valueFor(dstOutputs[i]); @@ -1022,7 +1040,7 @@ audio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(effect_descriptor_t return dstOutputs[outIdx]; } -status_t AudioPolicyManagerBase::registerEffect(effect_descriptor_t *desc, +status_t AudioPolicyManagerBase::registerEffect(const effect_descriptor_t *desc, audio_io_handle_t io, uint32_t strategy, int session, @@ -1234,11 +1252,11 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien Thread(false), #endif //AUDIO_POLICY_TEST mPrimaryOutput((audio_io_handle_t)0), - mAvailableOutputDevices((audio_devices_t)0), + mAvailableOutputDevices(AUDIO_DEVICE_NONE), mPhoneState(AudioSystem::MODE_NORMAL), mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), - mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false) + mA2dpSuspended(false), mHasA2dp(false), mHasUsb(false), mHasRemoteSubmix(false) { mpClientInterface = clientInterface; @@ -1308,7 +1326,7 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); - updateDeviceForStrategy(); + updateDevicesAndOutputs(); #ifdef AUDIO_POLICY_TEST if (mPrimaryOutput != 0) { @@ -1316,7 +1334,7 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien outputCmd.addInt(String8("set_id"), 0); mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString()); - mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER; + mTestDevice = AUDIO_DEVICE_OUT_SPEAKER; mTestSamplingRate = 44100; mTestFormat = AudioSystem::PCM_16_BIT; mTestChannels = AudioSystem::CHANNEL_OUT_STEREO; @@ -1463,7 +1481,7 @@ bool AudioPolicyManagerBase::threadLoop() mOutputs.removeItem(mPrimaryOutput); AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL); - outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER; + outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; mPrimaryOutput = mpClientInterface->openOutput(moduleHandle, &outputDesc->mDevice, &outputDesc->mSamplingRate, @@ -1761,17 +1779,18 @@ void AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) mOutputs.removeItem(output); } -SortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device) +SortedVector<audio_io_handle_t> AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device, + DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs) { SortedVector<audio_io_handle_t> outputs; ALOGVV("getOutputsForDevice() device %04x", device); - for (size_t i = 0; i < mOutputs.size(); i++) { + for (size_t i = 0; i < openOutputs.size(); i++) { ALOGVV("output %d isDuplicated=%d device=%04x", - i, mOutputs.valueAt(i)->isDuplicated(), mOutputs.valueAt(i)->supportedDevices()); - if ((device & mOutputs.valueAt(i)->supportedDevices()) == device) { - ALOGVV("getOutputsForDevice() found output %d", mOutputs.keyAt(i)); - outputs.add(mOutputs.keyAt(i)); + i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices()); + if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) { + ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i)); + outputs.add(openOutputs.keyAt(i)); } } return outputs; @@ -1795,8 +1814,8 @@ void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) { audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); - SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice); - SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice); + SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); + SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); if (!vectorsEqual(srcOutputs,dstOutputs)) { ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d", @@ -1919,7 +1938,7 @@ void AudioPolicyManagerBase::checkA2dpSuspend() audio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache) { - audio_devices_t device = (audio_devices_t)0; + audio_devices_t device = AUDIO_DEVICE_NONE; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); // check the following by order of priority to request a routing change if necessary: @@ -1964,7 +1983,7 @@ audio_devices_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_ // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE // and then return STRATEGY_MEDIA, but we want to return the empty set. if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) { - devices = (audio_devices_t)0; + devices = AUDIO_DEVICE_NONE; } else { AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream); devices = getDeviceForStrategy(strategy, true /*fromCache*/); @@ -2003,7 +2022,7 @@ void AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::str switch(stream) { case AudioSystem::MUSIC: checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); - updateDeviceForStrategy(); + updateDevicesAndOutputs(); break; default: break; @@ -2013,7 +2032,7 @@ void AudioPolicyManagerBase::handleNotificationRoutingForStream(AudioSystem::str audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache) { - uint32_t device = 0; + uint32_t device = AUDIO_DEVICE_NONE; if (fromCache) { ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x", @@ -2051,12 +2070,12 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { case AudioSystem::FORCE_BT_SCO: if (!isInCall() || strategy != STRATEGY_DTMF) { - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; if (device) break; } - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; if (device) break; // if SCO device is requested but no SCO device is available, fall back to default case // FALL THROUGH @@ -2066,29 +2085,29 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st if (mHasA2dp && !isInCall() && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && (getA2dpOutput() != 0) && !mA2dpSuspended) { - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; if (device) break; } - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; if (device) break; device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; if (device) break; device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE; if (device) break; device = mDefaultOutputDevice; - if (device == 0) { + if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); } break; @@ -2099,23 +2118,23 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st if (mHasA2dp && !isInCall() && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && (getA2dpOutput() != 0) && !mA2dpSuspended) { - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; if (device) break; } device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; if (device) break; device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; if (device) break; - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; if (device) break; device = mDefaultOutputDevice; - if (device == 0) { + if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); } break; @@ -2140,8 +2159,8 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st if (strategy == STRATEGY_SONIFICATION || !mStreams[AUDIO_STREAM_ENFORCED_AUDIBLE].mCanBeMuted) { - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; - if (device == 0) { + device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; + if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); } } @@ -2149,48 +2168,53 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st // FALL THROUGH case STRATEGY_MEDIA: { - uint32_t device2 = 0; - if (mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && + uint32_t device2 = AUDIO_DEVICE_NONE; + if (mHasRemoteSubmix + && mForceUse[AudioSystem::FOR_MEDIA] == AudioSystem::FORCE_REMOTE_SUBMIX) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; + } + if ((device2 == AUDIO_DEVICE_NONE) && + mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && (getA2dpOutput() != 0) && !mA2dpSuspended) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; } - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; } } - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; } - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; } - if (device2 == 0) { + if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; } - if (device2 == 0) { + if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; } - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; } - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; } - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; } - if (device2 == 0) { - device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; + if (device2 == AUDIO_DEVICE_NONE) { + device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; } // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or - // STRATEGY_ENFORCED_AUDIBLE, 0 otherwise + // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise device |= device2; if (device) break; device = mDefaultOutputDevice; - if (device == 0) { + if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); } } break; @@ -2201,14 +2225,15 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st } ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); - return (audio_devices_t)device; + return device; } -void AudioPolicyManagerBase::updateDeviceForStrategy() +void AudioPolicyManagerBase::updateDevicesAndOutputs() { for (int i = 0; i < NUM_STRATEGIES; i++) { mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); } + mPreviousOutputs = mOutputs; } uint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc, @@ -2245,7 +2270,8 @@ uint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor if (doMute || tempMute) { for (size_t j = 0; j < mOutputs.size(); j++) { AudioOutputDescriptor *desc = mOutputs.valueAt(j); - if ((desc->supportedDevices() & outputDesc->supportedDevices()) == 0) { + if ((desc->supportedDevices() & outputDesc->supportedDevices()) + == AUDIO_DEVICE_NONE) { continue; } audio_io_handle_t curOutput = mOutputs.keyAt(j); @@ -2304,16 +2330,16 @@ uint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, ALOGV("setOutputDevice() prevDevice %04x", prevDevice); - if (device != 0) { + if (device != AUDIO_DEVICE_NONE) { outputDesc->mDevice = device; } muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs); // Do not change the routing if: - // - the requested device is 0 + // - the requested device is AUDIO_DEVICE_NONE // - the requested device is the same as current device and force is not specified. // Doing this check here allows the caller to call setOutputDevice() without conditions - if ((device == 0 || device == prevDevice) && !force) { + if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); return muteWaitMs; } @@ -2356,7 +2382,7 @@ AudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) { - uint32_t device = 0; + uint32_t device = AUDIO_DEVICE_NONE; switch(inputSource) { case AUDIO_SOURCE_DEFAULT: @@ -2364,26 +2390,31 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) case AUDIO_SOURCE_VOICE_RECOGNITION: case AUDIO_SOURCE_VOICE_COMMUNICATION: if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && - mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { - device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; - } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) { - device = AudioSystem::DEVICE_IN_WIRED_HEADSET; - } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { - device = AudioSystem::DEVICE_IN_BUILTIN_MIC; + mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { + device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; + } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) { + device = AUDIO_DEVICE_IN_WIRED_HEADSET; + } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { + device = AUDIO_DEVICE_IN_BUILTIN_MIC; } break; case AUDIO_SOURCE_CAMCORDER: - if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BACK_MIC) { - device = AudioSystem::DEVICE_IN_BACK_MIC; - } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_BUILTIN_MIC) { - device = AudioSystem::DEVICE_IN_BUILTIN_MIC; + if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) { + device = AUDIO_DEVICE_IN_BACK_MIC; + } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { + device = AUDIO_DEVICE_IN_BUILTIN_MIC; } break; case AUDIO_SOURCE_VOICE_UPLINK: case AUDIO_SOURCE_VOICE_DOWNLINK: case AUDIO_SOURCE_VOICE_CALL: - if (mAvailableInputDevices & AudioSystem::DEVICE_IN_VOICE_CALL) { - device = AudioSystem::DEVICE_IN_VOICE_CALL; + if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { + device = AUDIO_DEVICE_IN_VOICE_CALL; + } + break; + case AUDIO_SOURCE_REMOTE_SUBMIX: + if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { + device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; } break; default: @@ -2391,13 +2422,25 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) break; } ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); - return (audio_devices_t)device; + return device; +} + +bool AudioPolicyManagerBase::isVirtualInputDevice(audio_devices_t device) +{ + if ((device & AUDIO_DEVICE_BIT_IN) != 0) { + device &= ~AUDIO_DEVICE_BIT_IN; + if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) + return true; + } + return false; } -audio_io_handle_t AudioPolicyManagerBase::getActiveInput() +audio_io_handle_t AudioPolicyManagerBase::getActiveInput(bool ignoreVirtualInputs) { for (size_t i = 0; i < mInputs.size(); i++) { - if (mInputs.valueAt(i)->mRefCount > 0) { + const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i); + if ((input_descriptor->mRefCount > 0) + && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { return mInputs.keyAt(i); } } @@ -2407,7 +2450,7 @@ audio_io_handle_t AudioPolicyManagerBase::getActiveInput() audio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) { - if (device == 0) { + if (device == AUDIO_DEVICE_NONE) { // this happens when forcing a route update and no track is active on an output. // In this case the returned category is not important. device = AUDIO_DEVICE_OUT_SPEAKER; @@ -2449,6 +2492,7 @@ AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategor case AUDIO_DEVICE_OUT_AUX_DIGITAL: case AUDIO_DEVICE_OUT_USB_ACCESSORY: case AUDIO_DEVICE_OUT_USB_DEVICE: + case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: default: return DEVICE_CATEGORY_SPEAKER; } @@ -2608,7 +2652,7 @@ float AudioPolicyManagerBase::computeVolume(int stream, AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); StreamDescriptor &streamDesc = mStreams[stream]; - if (device == 0) { + if (device == AUDIO_DEVICE_NONE) { device = outputDesc->device(); } @@ -2630,10 +2674,10 @@ float AudioPolicyManagerBase::computeVolume(int stream, // - if music is playing, always limit the volume to current music volume, // with a minimum threshold at -36dB so that notification is always perceived. const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); - if ((device & (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP | - AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | - AudioSystem::DEVICE_OUT_WIRED_HEADSET | - AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) && + if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | + AUDIO_DEVICE_OUT_WIRED_HEADSET | + AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) && ((stream_strategy == STRATEGY_SONIFICATION) || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) || (stream == AudioSystem::SYSTEM)) && @@ -2644,10 +2688,11 @@ float AudioPolicyManagerBase::computeVolume(int stream, // just stopped if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) || mLimitRingtoneVolume) { + audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/); float musicVol = computeVolume(AudioSystem::MUSIC, - mStreams[AudioSystem::MUSIC].getVolumeIndex(device), + mStreams[AudioSystem::MUSIC].getVolumeIndex(musicDevice), output, - device); + musicDevice); float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN; if (volume > minVol) { @@ -2765,7 +2810,7 @@ void AudioPolicyManagerBase::setStreamMute(int stream, { StreamDescriptor &streamDesc = mStreams[stream]; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); - if (device == 0) { + if (device == AUDIO_DEVICE_NONE) { device = outputDesc->device(); } @@ -2787,7 +2832,7 @@ void AudioPolicyManagerBase::setStreamMute(int stream, } if (--outputDesc->mMuteCount[stream] == 0) { checkAndSetVolume(stream, - streamDesc.getVolumeIndex((audio_devices_t)device), + streamDesc.getVolumeIndex(device), output, device, delayMs); @@ -2875,7 +2920,7 @@ AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( const IOProfile *profile) : mId(0), mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0), mLatency(0), - mFlags((audio_output_flags_t)0), mDevice((audio_devices_t)0), + mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mOutput1(0), mOutput2(0), mProfile(profile) { // clear usage count for all stream types @@ -3001,7 +3046,7 @@ status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) AudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile) : mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0), - mDevice((audio_devices_t)0), mRefCount(0), + mDevice(AUDIO_DEVICE_NONE), mRefCount(0), mInputSource(0), mProfile(profile) { } @@ -3258,12 +3303,17 @@ const struct StringToEnum sDeviceNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE), STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY), STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB), + STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX), STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET), STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL), STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL), STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC), + STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX), + STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET), + STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET), + STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY), }; const struct StringToEnum sFlagNameToEnumTable[] = { @@ -3338,7 +3388,7 @@ audio_devices_t AudioPolicyManagerBase::parseDeviceNames(char *name) } devName = strtok(NULL, "|"); } - return (audio_devices_t)device; + return device; } void AudioPolicyManagerBase::loadSamplingRates(char *name, IOProfile *profile) @@ -3455,7 +3505,7 @@ status_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module) } node = node->next; } - ALOGW_IF(profile->mSupportedDevices == (audio_devices_t)0, + ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, "loadInput() invalid supported devices"); ALOGW_IF(profile->mChannelMasks.size() == 0, "loadInput() invalid supported channel masks"); @@ -3463,7 +3513,7 @@ status_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module) "loadInput() invalid supported sampling rates"); ALOGW_IF(profile->mFormats.size() == 0, "loadInput() invalid supported formats"); - if ((profile->mSupportedDevices != (audio_devices_t)0) && + if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && (profile->mChannelMasks.size() != 0) && (profile->mSamplingRates.size() != 0) && (profile->mFormats.size() != 0)) { @@ -3498,7 +3548,7 @@ status_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module) } node = node->next; } - ALOGW_IF(profile->mSupportedDevices == (audio_devices_t)0, + ALOGW_IF(profile->mSupportedDevices == AUDIO_DEVICE_NONE, "loadOutput() invalid supported devices"); ALOGW_IF(profile->mChannelMasks.size() == 0, "loadOutput() invalid supported channel masks"); @@ -3506,7 +3556,7 @@ status_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module) "loadOutput() invalid supported sampling rates"); ALOGW_IF(profile->mFormats.size() == 0, "loadOutput() invalid supported formats"); - if ((profile->mSupportedDevices != (audio_devices_t)0) && + if ((profile->mSupportedDevices != AUDIO_DEVICE_NONE) && (profile->mChannelMasks.size() != 0) && (profile->mSamplingRates.size() != 0) && (profile->mFormats.size() != 0)) { @@ -3534,6 +3584,8 @@ void AudioPolicyManagerBase::loadHwModule(cnode *root) mHasA2dp = true; } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) { mHasUsb = true; + } else if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) { + mHasRemoteSubmix = true; } node = node->first_child; @@ -3590,16 +3642,18 @@ void AudioPolicyManagerBase::loadGlobalConfig(cnode *root) while (node) { if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { mAttachedOutputDevices = parseDeviceNames((char *)node->value); - ALOGW_IF(mAttachedOutputDevices == 0, "loadGlobalConfig() no attached output devices"); + ALOGW_IF(mAttachedOutputDevices == AUDIO_DEVICE_NONE, + "loadGlobalConfig() no attached output devices"); ALOGV("loadGlobalConfig() mAttachedOutputDevices %04x", mAttachedOutputDevices); } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { mDefaultOutputDevice = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable, ARRAY_SIZE(sDeviceNameToEnumTable), (char *)node->value); - ALOGW_IF(mDefaultOutputDevice == 0, "loadGlobalConfig() default device not specified"); + ALOGW_IF(mDefaultOutputDevice == AUDIO_DEVICE_NONE, + "loadGlobalConfig() default device not specified"); ALOGV("loadGlobalConfig() mDefaultOutputDevice %04x", mDefaultOutputDevice); } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { - mAvailableInputDevices = parseDeviceNames((char *)node->value); + mAvailableInputDevices = parseDeviceNames((char *)node->value) & ~AUDIO_DEVICE_BIT_IN; ALOGV("loadGlobalConfig() mAvailableInputDevices %04x", mAvailableInputDevices); } node = node->next; @@ -3637,7 +3691,7 @@ void AudioPolicyManagerBase::defaultAudioPolicyConfig(void) mDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER; mAttachedOutputDevices = AUDIO_DEVICE_OUT_SPEAKER; - mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC; + mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; module = new HwModule("primary"); diff --git a/audio/audio_hw_hal.cpp b/audio/audio_hw_hal.cpp index ab4d63a..07d735d 100644 --- a/audio/audio_hw_hal.cpp +++ b/audio/audio_hw_hal.cpp @@ -52,6 +52,69 @@ struct legacy_stream_in { AudioStreamIn *legacy_in; }; + +enum { + HAL_API_REV_1_0, + HAL_API_REV_2_0, + HAL_API_REV_NUM +} hal_api_rev; + +static uint32_t audio_device_conv_table[][HAL_API_REV_NUM] = +{ + /* output devices */ + { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE }, + { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER }, + { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET }, + { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE }, + { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO }, + { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET }, + { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT }, + { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP }, + { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES }, + { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER }, + { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL }, + { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET }, + { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET }, + { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT }, + /* input devices */ + { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION }, + { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT }, + { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC }, + { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET }, + { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET }, + { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL }, + { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL }, + { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC }, + { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT }, +}; + +static uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev) +{ + const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM; + uint32_t to_device = AUDIO_DEVICE_NONE; + uint32_t in_bit = 0; + + if (from_rev != HAL_API_REV_1_0) { + in_bit = from_device & AUDIO_DEVICE_BIT_IN; + from_device &= ~AUDIO_DEVICE_BIT_IN; + } + + while (from_device) { + uint32_t i = 31 - __builtin_clz(from_device); + uint32_t cur_device = (1 << i) | in_bit; + + for (i = 0; i < k_num_devices; i++) { + if (audio_device_conv_table[i][from_rev] == cur_device) { + to_device |= audio_device_conv_table[i][to_rev]; + break; + } + } + from_device &= ~cur_device; + } + return to_device; +} + + /** audio_stream_out implementation **/ static uint32_t out_get_sample_rate(const struct audio_stream *stream) { @@ -77,11 +140,11 @@ static size_t out_get_buffer_size(const struct audio_stream *stream) return out->legacy_out->bufferSize(); } -static uint32_t out_get_channels(const struct audio_stream *stream) +static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) { const struct legacy_stream_out *out = reinterpret_cast<const struct legacy_stream_out *>(stream); - return out->legacy_out->channels(); + return (audio_channel_mask_t) out->legacy_out->channels(); } static audio_format_t out_get_format(const struct audio_stream *stream) @@ -120,7 +183,18 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { struct legacy_stream_out *out = reinterpret_cast<struct legacy_stream_out *>(stream); - return out->legacy_out->setParameters(String8(kvpairs)); + int val; + String8 s8 = String8(kvpairs); + AudioParameter parms = AudioParameter(String8(kvpairs)); + + if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { + val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); + parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); + parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); + s8 = parms.toString(); + } + + return out->legacy_out->setParameters(s8); } static char * out_get_parameters(const struct audio_stream *stream, const char *keys) @@ -128,7 +202,18 @@ static char * out_get_parameters(const struct audio_stream *stream, const char * const struct legacy_stream_out *out = reinterpret_cast<const struct legacy_stream_out *>(stream); String8 s8; + int val; + s8 = out->legacy_out->getParameters(String8(keys)); + + AudioParameter parms = AudioParameter(s8); + if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { + val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); + parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); + parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); + s8 = parms.toString(); + } + return strdup(s8.string()); } @@ -206,11 +291,11 @@ static size_t in_get_buffer_size(const struct audio_stream *stream) return in->legacy_in->bufferSize(); } -static uint32_t in_get_channels(const struct audio_stream *stream) +static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) { const struct legacy_stream_in *in = reinterpret_cast<const struct legacy_stream_in *>(stream); - return in->legacy_in->channels(); + return (audio_channel_mask_t) in->legacy_in->channels(); } static audio_format_t in_get_format(const struct audio_stream *stream) @@ -248,7 +333,18 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) { struct legacy_stream_in *in = reinterpret_cast<struct legacy_stream_in *>(stream); - return in->legacy_in->setParameters(String8(kvpairs)); + int val; + AudioParameter parms = AudioParameter(String8(kvpairs)); + String8 s8 = String8(kvpairs); + + if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { + val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0); + parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); + parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); + s8 = parms.toString(); + } + + return in->legacy_in->setParameters(s8); } static char * in_get_parameters(const struct audio_stream *stream, @@ -257,7 +353,18 @@ static char * in_get_parameters(const struct audio_stream *stream, const struct legacy_stream_in *in = reinterpret_cast<const struct legacy_stream_in *>(stream); String8 s8; + int val; + s8 = in->legacy_in->getParameters(String8(keys)); + + AudioParameter parms = AudioParameter(s8); + if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) { + val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0); + parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING)); + parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val); + s8 = parms.toString(); + } + return strdup(s8.string()); } @@ -308,35 +415,6 @@ static inline const struct legacy_audio_device * to_cladev(const struct audio_hw return reinterpret_cast<const struct legacy_audio_device *>(dev); } -static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev) -{ - /* XXX: The old AudioHardwareInterface interface is not smart enough to - * tell us this, so we'll lie and basically tell AF that we support the - * below input/output devices and cross our fingers. To do things properly, - * audio hardware interfaces that need advanced features (like this) should - * convert to the new HAL interface and not use this wrapper. */ - - return (/* OUT */ - AUDIO_DEVICE_OUT_EARPIECE | - AUDIO_DEVICE_OUT_SPEAKER | - AUDIO_DEVICE_OUT_WIRED_HEADSET | - AUDIO_DEVICE_OUT_WIRED_HEADPHONE | - AUDIO_DEVICE_OUT_AUX_DIGITAL | - AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | - AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | - AUDIO_DEVICE_OUT_ALL_SCO | - AUDIO_DEVICE_OUT_DEFAULT | - /* IN */ - AUDIO_DEVICE_IN_COMMUNICATION | - AUDIO_DEVICE_IN_AMBIENT | - AUDIO_DEVICE_IN_BUILTIN_MIC | - AUDIO_DEVICE_IN_WIRED_HEADSET | - AUDIO_DEVICE_IN_AUX_DIGITAL | - AUDIO_DEVICE_IN_BACK_MIC | - AUDIO_DEVICE_IN_ALL_SCO | - AUDIO_DEVICE_IN_DEFAULT); -} - static int adev_init_check(const struct audio_hw_device *dev) { const struct legacy_audio_device *ladev = to_cladev(dev); @@ -421,6 +499,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev, if (!out) return -ENOMEM; + devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); + out->legacy_out = ladev->hwif->openOutputStream(devices, (int *) &config->format, &config->channel_mask, &config->sample_rate, &status); @@ -482,6 +562,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, if (!in) return -ENOMEM; + devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0); + in->legacy_in = ladev->hwif->openInputStream(devices, (int *) &config->format, &config->channel_mask, &config->sample_rate, &status, (AudioSystem::audio_in_acoustics)0); @@ -564,11 +646,10 @@ static int legacy_adev_open(const hw_module_t* module, const char* name, return -ENOMEM; ladev->device.common.tag = HARDWARE_DEVICE_TAG; - ladev->device.common.version = AUDIO_DEVICE_API_VERSION_1_0; + ladev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; ladev->device.common.module = const_cast<hw_module_t*>(module); ladev->device.common.close = legacy_adev_close; - ladev->device.get_supported_devices = adev_get_supported_devices; ladev->device.init_check = adev_init_check; ladev->device.set_voice_volume = adev_set_voice_volume; ladev->device.set_master_volume = adev_set_master_volume; diff --git a/audio/audio_policy_hal.cpp b/audio/audio_policy_hal.cpp index 37e6a6a..9e29bc4 100644 --- a/audio/audio_policy_hal.cpp +++ b/audio/audio_policy_hal.cpp @@ -137,14 +137,14 @@ static audio_io_handle_t ap_get_output(struct audio_policy *pol, audio_stream_type_t stream, uint32_t sampling_rate, audio_format_t format, - uint32_t channels, + audio_channel_mask_t channelMask, audio_output_flags_t flags) { struct legacy_audio_policy *lap = to_lap(pol); ALOGV("%s: tid %d", __func__, gettid()); return lap->apm->getOutput((AudioSystem::stream_type)stream, - sampling_rate, (int) format, channels, + sampling_rate, (int) format, channelMask, (AudioSystem::output_flags)flags); } @@ -174,11 +174,11 @@ static void ap_release_output(struct audio_policy *pol, static audio_io_handle_t ap_get_input(struct audio_policy *pol, audio_source_t inputSource, uint32_t sampling_rate, audio_format_t format, - uint32_t channels, + audio_channel_mask_t channelMask, audio_in_acoustics_t acoustics) { struct legacy_audio_policy *lap = to_lap(pol); - return lap->apm->getInput((int) inputSource, sampling_rate, (int) format, channels, + return lap->apm->getInput((int) inputSource, sampling_rate, (int) format, channelMask, (AudioSystem::audio_in_acoustics)acoustics); } @@ -266,14 +266,14 @@ static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol, } static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol, - struct effect_descriptor_s *desc) + const struct effect_descriptor_s *desc) { struct legacy_audio_policy *lap = to_lap(pol); return lap->apm->getOutputForEffect(desc); } static int ap_register_effect(struct audio_policy *pol, - struct effect_descriptor_s *desc, + const struct effect_descriptor_s *desc, audio_io_handle_t io, uint32_t strategy, int session, diff --git a/include/hardware_legacy/AudioPolicyInterface.h b/include/hardware_legacy/AudioPolicyInterface.h index 343f133..3ff68b9 100644 --- a/include/hardware_legacy/AudioPolicyInterface.h +++ b/include/hardware_legacy/AudioPolicyInterface.h @@ -66,11 +66,11 @@ public: // // indicate a change in device connection status - virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device, + virtual status_t setDeviceConnectionState(audio_devices_t device, AudioSystem::device_connection_state state, const char *device_address) = 0; // retrieve a device connection status - virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device, + virtual AudioSystem::device_connection_state getDeviceConnectionState(audio_devices_t device, const char *device_address) = 0; // indicate a change in phone state. Valid phones states are defined by AudioSystem::audio_mode virtual void setPhoneState(int state) = 0; @@ -147,8 +147,8 @@ public: virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream) = 0; // Audio effect management - virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) = 0; - virtual status_t registerEffect(effect_descriptor_t *desc, + virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc) = 0; + virtual status_t registerEffect(const effect_descriptor_t *desc, audio_io_handle_t io, uint32_t strategy, int session, diff --git a/include/hardware_legacy/AudioPolicyManagerBase.h b/include/hardware_legacy/AudioPolicyManagerBase.h index 96041c6..f110c20 100644 --- a/include/hardware_legacy/AudioPolicyManagerBase.h +++ b/include/hardware_legacy/AudioPolicyManagerBase.h @@ -72,10 +72,10 @@ public: virtual ~AudioPolicyManagerBase(); // AudioPolicyInterface - virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device, + virtual status_t setDeviceConnectionState(audio_devices_t device, AudioSystem::device_connection_state state, const char *device_address); - virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device, + virtual AudioSystem::device_connection_state getDeviceConnectionState(audio_devices_t device, const char *device_address); virtual void setPhoneState(int state); virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config); @@ -123,8 +123,8 @@ public: // return the enabled output devices for the given stream type virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream); - virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc); - virtual status_t registerEffect(effect_descriptor_t *desc, + virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc); + virtual status_t registerEffect(const effect_descriptor_t *desc, audio_io_handle_t io, uint32_t strategy, int session, @@ -330,7 +330,7 @@ protected: // 2 access to either current device selection (fromCache == true) or // "future" device selection (fromCache == false) when called from a context // where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND - // before updateDeviceForStrategy() is called. + // before updateDevicesAndOutputs() is called. virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy, bool fromCache); @@ -345,7 +345,9 @@ protected: virtual audio_devices_t getDeviceForInputSource(int inputSource); // return io handle of active input or 0 if no input is active - audio_io_handle_t getActiveInput(); + // Only considers inputs from physical devices (e.g. main mic, headset mic) when + // ignoreVirtualInputs is true. + audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true); // initialize volume curves for each strategy and device category void initializeVolumeCurves(); @@ -400,7 +402,7 @@ protected: // checks and if necessary changes outputs used for all strategies. // must be called every time a condition that affects the output choice for a given strategy // changes: connected device, phone state, force use... - // Must be called before updateDeviceForStrategy() + // Must be called before updateDevicesAndOutputs() void checkOutputForStrategy(routing_strategy strategy); // Same as checkOutputForStrategy() but for a all strategies in order of priority @@ -424,7 +426,7 @@ protected: // cached values are used by getDeviceForStrategy() if parameter fromCache is true. // Must be called after checkOutputForAllStrategies() - void updateDeviceForStrategy(); + void updateDevicesAndOutputs(); // true if current platform requires a specific output to be opened for this particular // set of parameters. This function is called by getOutput() and is implemented by platform @@ -452,7 +454,8 @@ protected: // extract one device relevant for volume control from multiple device selection static audio_devices_t getDeviceForVolume(audio_devices_t device); - SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device); + SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device, + DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs); bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1, SortedVector<audio_io_handle_t>& outputs2); @@ -498,10 +501,16 @@ protected: AudioPolicyClientInterface *mpClientInterface; // audio policy client interface audio_io_handle_t mPrimaryOutput; // primary output handle - DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs; // list of output descriptors + // list of descriptors for outputs currently opened + DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs; + // copy of mOutputs before setDeviceConnectionState() opens new outputs + // reset to mOutputs when updateDevicesAndOutputs() is called. + DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mPreviousOutputs; DefaultKeyedVector<audio_io_handle_t, AudioInputDescriptor *> mInputs; // list of input descriptors audio_devices_t mAvailableOutputDevices; // bit field of all available output devices audio_devices_t mAvailableInputDevices; // bit field of all available input devices + // without AUDIO_DEVICE_BIT_IN to allow direct bit + // field comparisons int mPhoneState; // current phone state AudioSystem::forced_config mForceUse[AudioSystem::NUM_FORCE_USE]; // current forced use configuration @@ -524,13 +533,12 @@ protected: bool mA2dpSuspended; // true if A2DP output is suspended bool mHasA2dp; // true on platforms with support for bluetooth A2DP bool mHasUsb; // true on platforms with support for USB audio + bool mHasRemoteSubmix; // true on platforms with support for remote presentation of a submix audio_devices_t mAttachedOutputDevices; // output devices always available on the platform audio_devices_t mDefaultOutputDevice; // output device selected by default at boot time // (must be in mAttachedOutputDevices) Vector <HwModule *> mHwModules; - Vector <IOProfile *> mOutputProfiles; // output profiles loaded from audio_policy.conf - Vector <IOProfile *> mInputProfiles; // input profiles loaded from audio_policy.conf #ifdef AUDIO_POLICY_TEST Mutex mLock; @@ -553,6 +561,7 @@ private: // updates device caching and output for streams that can influence the // routing of notifications void handleNotificationRoutingForStream(AudioSystem::stream_type stream); + static bool isVirtualInputDevice(audio_devices_t device); }; }; diff --git a/include/hardware_legacy/AudioSystemLegacy.h b/include/hardware_legacy/AudioSystemLegacy.h index a40622a..7cf7672 100644 --- a/include/hardware_legacy/AudioSystemLegacy.h +++ b/include/hardware_legacy/AudioSystemLegacy.h @@ -226,6 +226,8 @@ public: TX_DISABLE = 0 }; + // DO NOT USE: the "audio_devices" enumeration below is obsolete, use type "audio_devices_t" and + // audio device enumeration from system/audio.h instead. enum audio_devices { // output devices DEVICE_OUT_EARPIECE = 0x1, @@ -286,6 +288,7 @@ public: FORCE_ANALOG_DOCK, FORCE_DIGITAL_DOCK, FORCE_NO_BT_A2DP, + FORCE_REMOTE_SUBMIX, NUM_FORCE_CONFIG, FORCE_DEFAULT = FORCE_NONE }; @@ -318,10 +321,16 @@ public: #if 1 static bool isOutputDevice(audio_devices device) { - return audio_is_output_device((audio_devices_t)device); + if ((popcount(device) == 1) && ((device & ~DEVICE_OUT_ALL) == 0)) + return true; + else + return false; } static bool isInputDevice(audio_devices device) { - return audio_is_input_device((audio_devices_t)device); + if ((popcount(device) == 1) && ((device & ~DEVICE_IN_ALL) == 0)) + return true; + else + return false; } static bool isA2dpDevice(audio_devices device) { return audio_is_a2dp_device((audio_devices_t)device); |