diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp index baeae8b709..0beb65de91 100644 --- a/media/libaudioclient/AudioSystem.cpp +++ b/media/libaudioclient/AudioSystem.cpp @@ -784,7 +784,8 @@ const sp AudioSystem::get_audio_policy_service() status_t AudioSystem::setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { const sp& aps = AudioSystem::get_audio_policy_service(); const char *address = ""; @@ -798,7 +799,7 @@ status_t AudioSystem::setDeviceConnectionState(audio_devices_t device, if (device_name != NULL) { name = device_name; } - return aps->setDeviceConnectionState(device, state, address, name); + return aps->setDeviceConnectionState(device, state, address, name, encodedFormat); } audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device, @@ -812,7 +813,8 @@ audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t d status_t AudioSystem::handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { const sp& aps = AudioSystem::get_audio_policy_service(); const char *address = ""; @@ -826,7 +828,7 @@ status_t AudioSystem::handleDeviceConfigChange(audio_devices_t device, if (device_name != NULL) { name = device_name; } - return aps->handleDeviceConfigChange(device, address, name); + return aps->handleDeviceConfigChange(device, address, name, encodedFormat); } status_t AudioSystem::setPhoneState(audio_mode_t state) diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp index 272415c59f..0fae2a1f07 100644 --- a/media/libaudioclient/IAudioPolicyService.cpp +++ b/media/libaudioclient/IAudioPolicyService.cpp @@ -108,7 +108,8 @@ public: audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -116,6 +117,7 @@ public: data.writeInt32(static_cast (state)); data.writeCString(device_address); data.writeCString(device_name); + data.writeInt32(static_cast (encodedFormat)); remote()->transact(SET_DEVICE_CONNECTION_STATE, data, &reply); return static_cast (reply.readInt32()); } @@ -134,13 +136,15 @@ public: virtual status_t handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(static_cast (device)); data.writeCString(device_address); data.writeCString(device_name); + data.writeInt32(static_cast (encodedFormat)); remote()->transact(HANDLE_DEVICE_CONFIG_CHANGE, data, &reply); return static_cast (reply.readInt32()); } @@ -1121,6 +1125,7 @@ status_t BnAudioPolicyService::onTransact( static_cast (data.readInt32()); const char *device_address = data.readCString(); const char *device_name = data.readCString(); + audio_format_t codecFormat = static_cast (data.readInt32()); if (device_address == nullptr || device_name == nullptr) { ALOGE("Bad Binder transaction: SET_DEVICE_CONNECTION_STATE for device %u", device); reply->writeInt32(static_cast (BAD_VALUE)); @@ -1128,7 +1133,8 @@ status_t BnAudioPolicyService::onTransact( reply->writeInt32(static_cast (setDeviceConnectionState(device, state, device_address, - device_name))); + device_name, + codecFormat))); } return NO_ERROR; } break; @@ -1154,13 +1160,16 @@ status_t BnAudioPolicyService::onTransact( static_cast (data.readInt32()); const char *device_address = data.readCString(); const char *device_name = data.readCString(); + audio_format_t codecFormat = + static_cast (data.readInt32()); if (device_address == nullptr || device_name == nullptr) { ALOGE("Bad Binder transaction: HANDLE_DEVICE_CONFIG_CHANGE for device %u", device); reply->writeInt32(static_cast (BAD_VALUE)); } else { reply->writeInt32(static_cast (handleDeviceConfigChange(device, device_address, - device_name))); + device_name, + codecFormat))); } return NO_ERROR; } break; diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h index 781e9dfc41..2b4a373558 100644 --- a/media/libaudioclient/include/media/AudioSystem.h +++ b/media/libaudioclient/include/media/AudioSystem.h @@ -209,12 +209,14 @@ public: // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions) // static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, - const char *device_address, const char *device_name); + const char *device_address, const char *device_name, + audio_format_t encodedFormat); static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address); static status_t handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name); + const char *device_name, + audio_format_t encodedFormat); static status_t setPhoneState(audio_mode_t state); static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config); static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage); diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h index fb4fe9302f..75de8e9725 100644 --- a/media/libaudioclient/include/media/IAudioPolicyService.h +++ b/media/libaudioclient/include/media/IAudioPolicyService.h @@ -44,12 +44,14 @@ public: virtual status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name) = 0; + const char *device_name, + audio_format_t encodedFormat) = 0; virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address) = 0; virtual status_t handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name) = 0; + const char *device_name, + audio_format_t encodedFormat) = 0; virtual status_t setPhoneState(audio_mode_t state) = 0; virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) = 0; diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index 1c2b9d7c8b..8bfb7360c5 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -75,14 +75,16 @@ public: virtual status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name) = 0; + const char *device_name, + audio_format_t encodedFormat) = 0; // retrieve a device connection status virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address) = 0; // indicate a change in device configuration virtual status_t handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name) = 0; + const char *device_name, + audio_format_t encodedFormat) = 0; // indicate a change in phone state. Valid phones states are defined by audio_mode_t virtual void setPhoneState(audio_mode_t state) = 0; // force using a specific device category for the specified usage diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h index 46a2a40453..837ca47fa3 100644 --- a/services/audiopolicy/common/include/policy.h +++ b/services/audiopolicy/common/include/policy.h @@ -75,6 +75,21 @@ static inline bool device_distinguishes_on_address(audio_devices_t device) ((device & APM_AUDIO_DEVICE_OUT_MATCH_ADDRESS_ALL) != 0)); } +/** + * Check whether audio device has encoding capability. + * + * @param[in] device to consider + * + * @return true if device has encoding capability, false otherwise.. + */ +static inline bool device_has_encoding_capability(audio_devices_t device) +{ + if (device & AUDIO_DEVICE_OUT_ALL_A2DP) { + return true; + } + return false; +} + /** * Returns the priority of a given audio source for capture. The priority is used when more than one * capture session is active on a given input stream to determine which session drives routing and diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h index 14b995b25a..e1ecc61eda 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h @@ -154,6 +154,7 @@ public: void setDevices(const DeviceVector &devices) { mDevices = devices; } bool sharesHwModuleWith(const sp& outputDesc); virtual DeviceVector supportedDevices() const; + virtual bool deviceSupportsEncodedFormats(audio_devices_t device); virtual uint32_t latency(); virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); } virtual bool isFixedVolume(audio_devices_t device); diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h index b581665caf..cc43fe69e0 100644 --- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h @@ -44,8 +44,18 @@ public: const FormatVector& encodedFormats() const { return mEncodedFormats; } + audio_format_t getEncodedFormat() { return mCurrentEncodedFormat; } + + void setEncodedFormat(audio_format_t format) { + mCurrentEncodedFormat = format; + } + bool equals(const sp& other) const; + bool hasCurrentEncodedFormat() const; + + bool supportsFormat(audio_format_t format); + // AudioPortConfig virtual sp getAudioPort() const { return (AudioPort*) this; } virtual void toAudioPortConfig(struct audio_port_config *dstConfig, @@ -69,6 +79,7 @@ private: audio_devices_t mDeviceType; FormatVector mEncodedFormats; audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE; + audio_format_t mCurrentEncodedFormat; }; class DeviceVector : public SortedVector > @@ -88,9 +99,10 @@ public: audio_devices_t types() const { return mDeviceTypes; } - // If 'address' is empty, a device with a non-empty address may be returned - // if there is no device with the specified 'type' and empty address. - sp getDevice(audio_devices_t type, const String8 &address = {}) const; + // If 'address' is empty and 'codec' is AUDIO_FORMAT_DEFAULT, a device with a non-empty + // address may be returned if there is no device with the specified 'type' and empty address. + sp getDevice(audio_devices_t type, const String8 &address, + audio_format_t codec) const; DeviceVector getDevicesFromTypeMask(audio_devices_t types) const; /** diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h index d7dc4b009e..eb34da448a 100644 --- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h +++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h @@ -130,9 +130,11 @@ class HwModuleCollection : public Vector > public: sp getModuleFromName(const char *name) const; - sp getModuleForDeviceTypes(audio_devices_t device) const; + sp getModuleForDeviceTypes(audio_devices_t device, + audio_format_t encodedFormat) const; - sp getModuleForDevice(const sp &device) const; + sp getModuleForDevice(const sp &device, + audio_format_t encodedFormat) const; DeviceVector getAvailableDevicesFromModuleName(const char *name, const DeviceVector &availableDevices) const; @@ -149,6 +151,7 @@ public: * @param type of the device requested * @param address of the device requested * @param name of the device that requested + * @param encodedFormat if not AUDIO_FORMAT_DEFAULT, must match one supported format * @param matchAddress true if a strong match is required * @param allowToCreate true if allowed to create dynamic device (e.g. hdmi, usb...) * @return device descriptor associated to the type (and address if matchAddress is true) @@ -156,6 +159,7 @@ public: sp getDeviceDescriptor(const audio_devices_t type, const char *address, const char *name, + audio_format_t encodedFormat, bool allowToCreate = false, bool matchAddress = true) const; @@ -171,7 +175,8 @@ public: */ sp createDevice(const audio_devices_t type, const char *address, - const char *name) const; + const char *name, + const audio_format_t encodedFormat) const; /** * @brief cleanUpForDevice: loop on all profiles of all modules to remove device from diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h index d0c05a5af3..dc409a7439 100644 --- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h +++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h @@ -94,7 +94,10 @@ public: bool supportsDeviceTypes(audio_devices_t device) const { if (audio_is_output_devices(device)) { - return mSupportedDevices.types() & device; + if (deviceSupportsEncodedFormats(device)) { + return mSupportedDevices.types() & device; + } + return false; } return mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN); } @@ -116,6 +119,16 @@ public: return mSupportedDevices.contains(device); } + bool deviceSupportsEncodedFormats(audio_devices_t device) const + { + DeviceVector deviceList = + mSupportedDevices.getDevicesFromTypeMask(device); + if (!deviceList.empty()) { + return deviceList.itemAt(0)->hasCurrentEncodedFormat(); + } + return false; + } + void clearSupportedDevices() { mSupportedDevices.clear(); } void addSupportedDevice(const sp &device) { diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index 643cbd100d..57328f0ed7 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -364,6 +364,16 @@ DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector return filteredDevices.filter(devices); } +bool SwAudioOutputDescriptor::deviceSupportsEncodedFormats(audio_devices_t device) +{ + if (isDuplicated()) { + return (mOutput1->deviceSupportsEncodedFormats(device) + || mOutput2->deviceSupportsEncodedFormats(device)); + } else { + return mProfile->deviceSupportsEncodedFormats(device); + } +} + uint32_t SwAudioOutputDescriptor::latency() { if (isDuplicated()) { @@ -687,7 +697,9 @@ audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const for (size_t i = 0; i < size(); i++) { sp outputDesc = valueAt(i); if (!outputDesc->isDuplicated() && - outputDesc->devices().types() & AUDIO_DEVICE_OUT_ALL_A2DP) { + outputDesc->devices().types() & AUDIO_DEVICE_OUT_ALL_A2DP && + outputDesc->deviceSupportsEncodedFormats( + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)) { return this->keyAt(i); } } diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp index d18091ca25..799950c534 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp @@ -296,7 +296,8 @@ sp AudioPolicyMixCollection::getDeviceAndMixForInputSource( // assuming PolicyMix only for remote submix for input // so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX audio_devices_t device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; - auto mixDevice = availDevices.getDevice(device, mix->mDeviceAddress); + auto mixDevice = + availDevices.getDevice(device, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT); if (mixDevice != nullptr) { if (policyMix != NULL) { *policyMix = mix; diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp index 01111c5150..2ed8455458 100644 --- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp @@ -18,6 +18,7 @@ //#define LOG_NDEBUG 0 #include +#include #include "DeviceDescriptor.h" #include "TypeConverter.h" #include "AudioGain.h" @@ -37,6 +38,7 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc AUDIO_PORT_ROLE_SOURCE), mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats) { + mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT; if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) { mAddress = String8("0"); } @@ -45,6 +47,12 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc mEncodedFormats.add(AUDIO_FORMAT_AC3); mEncodedFormats.add(AUDIO_FORMAT_IEC61937); } + // For backward compatibility always indicate support for SBC and AAC if no + // supported format is listed in the configuration file + if ((type & AUDIO_DEVICE_OUT_ALL_A2DP) != 0 && mEncodedFormats.isEmpty()) { + mEncodedFormats.add(AUDIO_FORMAT_SBC); + mEncodedFormats.add(AUDIO_FORMAT_AAC); + } } audio_port_handle_t DeviceDescriptor::getId() const @@ -58,21 +66,49 @@ void DeviceDescriptor::attach(const sp& module) mId = getNextUniqueId(); } -void DeviceDescriptor::detach() -{ +void DeviceDescriptor::detach() { mId = AUDIO_PORT_HANDLE_NONE; AudioPort::detach(); } +template +bool checkEqual(const T& f1, const T& f2) +{ + std::set s1(f1.begin(), f1.end()); + std::set s2(f2.begin(), f2.end()); + return s1 == s2; +} + bool DeviceDescriptor::equals(const sp& other) const { // Devices are considered equal if they: // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE) // - have the same address + // - have the same encodingFormats (if device supports encoding) if (other == 0) { return false; } - return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress); + + return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress) && + checkEqual(mEncodedFormats, other->mEncodedFormats); +} + +bool DeviceDescriptor::hasCurrentEncodedFormat() const +{ + if (!device_has_encoding_capability(type())) { + return true; + } + return (mCurrentEncodedFormat != AUDIO_FORMAT_DEFAULT); +} + +bool DeviceDescriptor::supportsFormat(audio_format_t format) +{ + for (const auto& devFormat : mEncodedFormats) { + if (devFormat == format) { + return true; + } + } + return false; } void DeviceVector::refreshTypes() @@ -167,12 +203,17 @@ audio_devices_t DeviceVector::getDeviceTypesFromHwModule(audio_module_handle_t m return deviceTypes; } -sp DeviceVector::getDevice(audio_devices_t type, const String8& address) const +sp DeviceVector::getDevice(audio_devices_t type, const String8& address, + audio_format_t format) const { sp device; for (size_t i = 0; i < size(); i++) { if (itemAt(i)->type() == type) { - if (address == "" || itemAt(i)->address() == address) { + // Assign device if address is empty or matches and + // format is default or matches + if (((address == "" || itemAt(i)->address() == address) && + format == AUDIO_FORMAT_DEFAULT) || + itemAt(i)->supportsFormat(format)) { device = itemAt(i); if (itemAt(i)->address() == address) { break; @@ -180,8 +221,8 @@ sp DeviceVector::getDevice(audio_devices_t type, const String8 } } } - ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p", - __func__, type, address.string(), device.get()); + ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x", + __func__, type, address.string(), device.get(), format); return device; } diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp index 7d2d094f4e..85d9bcec88 100644 --- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp @@ -273,32 +273,34 @@ sp HwModuleCollection::getModuleFromName(const char *name) const return nullptr; } -sp HwModuleCollection::getModuleForDeviceTypes(audio_devices_t device) const +sp HwModuleCollection::getModuleForDeviceTypes(audio_devices_t type, + audio_format_t encodedFormat) const { for (const auto& module : *this) { - const auto& profiles = audio_is_output_device(device) ? + const auto& profiles = audio_is_output_device(type) ? module->getOutputProfiles() : module->getInputProfiles(); for (const auto& profile : profiles) { - if (profile->supportsDeviceTypes(device)) { - return module; + if (profile->supportsDeviceTypes(type)) { + if (encodedFormat != AUDIO_FORMAT_DEFAULT) { + DeviceVector declaredDevices = module->getDeclaredDevices(); + sp deviceDesc = + declaredDevices.getDevice(type, String8(), encodedFormat); + if (deviceDesc) { + return module; + } + } else { + return module; + } } } } return nullptr; } -sp HwModuleCollection::getModuleForDevice(const sp &device) const +sp HwModuleCollection::getModuleForDevice(const sp &device, + audio_format_t encodedFormat) const { - for (const auto& module : *this) { - const auto& profiles = audio_is_output_device(device->type()) ? - module->getOutputProfiles() : module->getInputProfiles(); - for (const auto& profile : profiles) { - if (profile->supportsDevice(device)) { - return module; - } - } - } - return nullptr; + return getModuleForDeviceTypes(device->type(), encodedFormat); } DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName( @@ -314,6 +316,7 @@ DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName( sp HwModuleCollection::getDeviceDescriptor(const audio_devices_t deviceType, const char *address, const char *name, + const audio_format_t encodedFormat, bool allowToCreate, bool matchAddress) const { @@ -325,8 +328,14 @@ sp HwModuleCollection::getDeviceDescriptor(const audio_devices for (const auto& hwModule : *this) { DeviceVector moduleDevices = hwModule->getAllDevices(); - auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress); + auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress, encodedFormat); if (moduleDevice) { + if (encodedFormat != AUDIO_FORMAT_DEFAULT) { + moduleDevice->setEncodedFormat(encodedFormat); + if (moduleDevice->address() != devAddress) { + moduleDevice->setAddress(devAddress); + } + } if (allowToCreate) { moduleDevice->attach(hwModule); } @@ -338,14 +347,15 @@ sp HwModuleCollection::getDeviceDescriptor(const audio_devices name, deviceType, address); return nullptr; } - return createDevice(deviceType, address, name); + return createDevice(deviceType, address, name, encodedFormat); } sp HwModuleCollection::createDevice(const audio_devices_t type, const char *address, - const char *name) const + const char *name, + const audio_format_t encodedFormat) const { - sp hwModule = getModuleForDeviceTypes(type); + sp hwModule = getModuleForDeviceTypes(type, encodedFormat); if (hwModule == 0) { ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type, address); @@ -354,8 +364,9 @@ sp HwModuleCollection::createDevice(const audio_devices_t type sp device = new DeviceDescriptor(type, String8(name)); device->setName(String8(name)); device->setAddress(String8(address)); + device->setEncodedFormat(encodedFormat); - // Add the device to the list of dynamic devices + // Add the device to the list of dynamic devices hwModule->addDynamicDevice(device); // Reciprocally attach the device to the module device->attach(hwModule); @@ -370,7 +381,8 @@ sp HwModuleCollection::createDevice(const audio_devices_t type if (profile->supportsDevice(device, false /*matchAdress*/)) { // @todo quid of audio profile? import the profile from device of the same type? - const auto &isoTypeDeviceForProfile = profile->getSupportedDevices().getDevice(type); + const auto &isoTypeDeviceForProfile = + profile->getSupportedDevices().getDevice(type, String8(), AUDIO_FORMAT_DEFAULT); device->importAudioPort(isoTypeDeviceForProfile, true /* force */); ALOGV("%s: adding device %s to profile %s", __FUNCTION__, diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp index 1154654f85..98d375c115 100644 --- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp @@ -140,6 +140,8 @@ struct DevicePortTraits : public AndroidCollectionTraits. */ /** optional: device address, char string less than 64. */ static constexpr const char *address = "address"; + /** optional: the list of encoded audio formats that are known to be supported. */ + static constexpr const char *encodedFormats = "encodedFormats"; }; static Return deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext); @@ -511,7 +513,13 @@ Return DevicePortTraits::deserialize(const xmlNode *c ALOGW("%s: bad type %08x", __func__, type); return Status::fromStatusT(BAD_VALUE); } - Element deviceDesc = new DeviceDescriptor(type, String8(name.c_str())); + std::string encodedFormatsLiteral = getXmlAttribute(cur, Attributes::encodedFormats); + ALOGV("%s: %s %s=%s", __func__, tag, Attributes::encodedFormats, encodedFormatsLiteral.c_str()); + FormatVector encodedFormats; + if (!encodedFormatsLiteral.empty()) { + encodedFormats = formatsFromString(encodedFormatsLiteral, " "); + } + Element deviceDesc = new DeviceDescriptor(type, encodedFormats, String8(name.c_str())); std::string address = getXmlAttribute(cur, Attributes::address); if (!address.empty()) { diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp index 3d68cd8834..cc5a025d80 100644 --- a/services/audiopolicy/enginedefault/src/Engine.cpp +++ b/services/audiopolicy/enginedefault/src/Engine.cpp @@ -506,7 +506,7 @@ audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy, if (strategy != STRATEGY_SONIFICATION) { // no sonification on remote submix (e.g. WFD) if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, - String8("0")) != 0) { + String8("0"), AUDIO_FORMAT_DEFAULT) != 0) { device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; } } diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index 5c8a799d50..a03e20d276 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -81,9 +81,11 @@ static const std::vector surroundChannelMasksOrder = {{ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { - status_t status = setDeviceConnectionStateInt(device, state, device_address, device_name); + status_t status = setDeviceConnectionStateInt(device, state, device_address, + device_name, encodedFormat); nextAudioPortGeneration(); return status; } @@ -101,16 +103,17 @@ void AudioPolicyManager::broadcastDeviceConnectionState(const sp device = - mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, + mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat, state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE); if (device == 0) { return INVALID_OPERATION; @@ -133,10 +136,22 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT ALOGW("%s() device already connected: %s", __func__, device->toString().c_str()); return INVALID_OPERATION; } - ALOGV("%s() connecting device %s", __func__, device->toString().c_str()); + ALOGV("%s() connecting device %s format %x", + __func__, device->toString().c_str(), encodedFormat); // register new device as available - if (mAvailableOutputDevices.add(device) < 0) { + index = mAvailableOutputDevices.add(device); + if (index >= 0) { + sp module = mHwModules.getModuleForDevice(device, encodedFormat); + if (module == 0) { + ALOGD("setDeviceConnectionState() could not find HW module for device %s", + device->toString().c_str()); + mAvailableOutputDevices.remove(device); + return INVALID_OPERATION; + } + ALOGV("setDeviceConnectionState() module name=%s", module->getName()); + mAvailableOutputDevices[index]->attach(module); + } else { return NO_MEMORY; } @@ -178,6 +193,9 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT checkOutputsForDevice(device, state, outputs); + // Reset active device codec + device->setEncodedFormat(AUDIO_FORMAT_DEFAULT); + // Propagate device availability to Engine mEngine->setDeviceConnectionState(device, state); } break; @@ -248,6 +266,13 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT ALOGW("%s() device already connected: %s", __func__, device->toString().c_str()); return INVALID_OPERATION; } + sp module = mHwModules.getModuleForDevice(device, AUDIO_FORMAT_DEFAULT); + if (module == NULL) { + ALOGW("setDeviceConnectionState(): could not find HW module for device %s", + device->toString().c_str()); + return INVALID_OPERATION; + } + // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic // parameters on newly connected devices (instead of opening the inputs...) broadcastDeviceConnectionState(device, state); @@ -318,7 +343,8 @@ audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devi const char *device_address) { sp devDesc = - mHwModules.getDeviceDescriptor(device, device_address, "", false /* allowToCreate */, + mHwModules.getDeviceDescriptor(device, device_address, "", AUDIO_FORMAT_DEFAULT, + false /* allowToCreate */, (strlen(device_address) != 0)/*matchAddress*/); if (devDesc == 0) { @@ -338,50 +364,61 @@ audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devi return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; } - return (deviceVector->getDevice(device, String8(device_address)) != 0) ? + return (deviceVector->getDevice( + device, String8(device_address), AUDIO_FORMAT_DEFAULT) != 0) ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; } status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { status_t status; String8 reply; AudioParameter param; int isReconfigA2dpSupported = 0; - ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s", - device, device_address, device_name); + ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s encodedFormat: 0x%X", + device, device_address, device_name, encodedFormat); // connect/disconnect only 1 device at a time if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; // Check if the device is currently connected - sp devDesc = - mHwModules.getDeviceDescriptor(device, device_address, device_name); - if (devDesc == 0 || mAvailableOutputDevices.indexOf(devDesc) < 0) { + DeviceVector availableDevices = getAvailableOutputDevices(); + DeviceVector deviceList = availableDevices.getDevicesFromTypeMask(device); + if (deviceList.empty()) { // Nothing to do: device is not connected return NO_ERROR; } + sp devDesc = deviceList.itemAt(0); // For offloaded A2DP, Hw modules may have the capability to - // configure codecs. Check if any of the loaded hw modules - // supports this. - // If supported, send a set parameter to configure A2DP codecs - // and return. No need to toggle device state. + // configure codecs. + // Handle two specific cases by sending a set parameter to + // configure A2DP codecs. No need to toggle device state. + // Case 1: A2DP active device switches from primary to primary + // module + // Case 2: A2DP device config changes on primary module. if (device & AUDIO_DEVICE_OUT_ALL_A2DP) { - reply = mpClientInterface->getParameters( - AUDIO_IO_HANDLE_NONE, - String8(AudioParameter::keyReconfigA2dpSupported)); - AudioParameter repliedParameters(reply); - repliedParameters.getInt( - String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported); - if (isReconfigA2dpSupported) { - const String8 key(AudioParameter::keyReconfigA2dp); - param.add(key, String8("true")); - mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); - return NO_ERROR; + sp module = mHwModules.getModuleForDeviceTypes(device, encodedFormat); + audio_module_handle_t primaryHandle = mPrimaryOutput->getModuleHandle(); + if (availablePrimaryOutputDevices().contains(devDesc) && + (module != 0 && module->getHandle() == primaryHandle)) { + reply = mpClientInterface->getParameters( + AUDIO_IO_HANDLE_NONE, + String8(AudioParameter::keyReconfigA2dpSupported)); + AudioParameter repliedParameters(reply); + repliedParameters.getInt( + String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported); + if (isReconfigA2dpSupported) { + const String8 key(AudioParameter::keyReconfigA2dp); + param.add(key, String8("true")); + mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); + devDesc->setEncodedFormat(encodedFormat); + return NO_ERROR; + } } } @@ -389,7 +426,8 @@ status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device, // This will force reading again the device configuration status = setDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, - device_address, device_name); + device_address, device_name, + devDesc->getEncodedFormat()); if (status != NO_ERROR) { ALOGW("handleDeviceConfigChange() error disabling connection state: %d", status); @@ -398,7 +436,7 @@ status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device, status = setDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, - device_address, device_name); + device_address, device_name, encodedFormat); if (status != NO_ERROR) { ALOGW("handleDeviceConfigChange() error enabling connection state: %d", status); @@ -464,15 +502,18 @@ sp AudioPolicyManager::createTelephonyPatch( } if (isRx) { patchBuilder.addSink(device). - addSource(mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX)); + addSource(mAvailableInputDevices.getDevice( + AUDIO_DEVICE_IN_TELEPHONY_RX, String8(), AUDIO_FORMAT_DEFAULT)); } else { patchBuilder.addSource(device). - addSink(mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX)); + addSink(mAvailableOutputDevices.getDevice( + AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT)); } // @TODO: still ignoring the address, or not dealing platform with mutliple telephonydevices const sp outputDevice = isRx ? - device : mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX); + device : mAvailableOutputDevices.getDevice( + AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT); SortedVector outputs = getOutputsForDevices(DeviceVector(outputDevice), mOutputs); audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID); @@ -736,6 +777,10 @@ sp AudioPolicyManager::getProfileForOutput( if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) { continue; } + // reject profiles if connected device does not support codec + if (!curProfile->deviceSupportsEncodedFormats(devices.types())) { + continue; + } if (!directOnly) return curProfile; // when searching for direct outputs, if several profiles are compatible, give priority // to one with offload capability @@ -840,7 +885,8 @@ status_t AudioPolicyManager::getOutputForAttrInt(audio_attributes_t *resultAttr, *output = desc->mIoHandle; AudioMix *mix = desc->mPolicyMix; sp deviceDesc = - mAvailableOutputDevices.getDevice(mix->mDeviceType, mix->mDeviceAddress); + mAvailableOutputDevices.getDevice( + mix->mDeviceType, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT); *selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE; ALOGV("%s returns output %d", __func__, *output); return NO_ERROR; @@ -883,7 +929,8 @@ status_t AudioPolicyManager::getOutputForAttrInt(audio_attributes_t *resultAttr, *output = AUDIO_IO_HANDLE_NONE; if (!msdDevices.isEmpty()) { *output = getOutputForDevices(msdDevices, session, *stream, config, flags); - sp deviceDesc = mAvailableOutputDevices.getDevice(deviceType); + sp deviceDesc = + mAvailableOutputDevices.getDevice(deviceType, String8(), AUDIO_FORMAT_DEFAULT); if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(deviceDesc) == NO_ERROR) { ALOGV("%s() Using MSD devices %s instead of device %s", __func__, msdDevices.toString().c_str(), deviceDesc->toString().c_str()); @@ -1158,7 +1205,7 @@ status_t AudioPolicyManager::getBestMsdAudioProfileFor(const sp deviceModule = mHwModules.getModuleForDevice(outputDevice); + sp deviceModule = mHwModules.getModuleForDevice(outputDevice, AUDIO_FORMAT_DEFAULT); if (deviceModule == nullptr) { ALOGE("%s() unable to get module for %s", __func__, outputDevice->toString().c_str()); return NO_INIT; @@ -1456,7 +1503,8 @@ status_t AudioPolicyManager::startSource(const sp& outp } else { newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX; } - devices.add(mAvailableOutputDevices.getDevice(newDeviceType, String8(address))); + devices.add(mAvailableOutputDevices.getDevice(newDeviceType, + String8(address), AUDIO_FORMAT_DEFAULT)); } // requiresMuteCheck is false when we can bypass mute strategy. @@ -1574,7 +1622,8 @@ status_t AudioPolicyManager::startSource(const sp& outp setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address, - "remote-submix"); + "remote-submix", + AUDIO_FORMAT_DEFAULT); } return NO_ERROR; @@ -1620,7 +1669,7 @@ status_t AudioPolicyManager::stopSource(const sp& outpu setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, outputDesc->mPolicyMix->mDeviceAddress, - "remote-submix"); + "remote-submix", AUDIO_FORMAT_DEFAULT); } } bool forceDeviceUpdate = false; @@ -1812,7 +1861,8 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, } *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE; device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, - String8(attr->tags + strlen("addr="))); + String8(attr->tags + strlen("addr=")), + AUDIO_FORMAT_DEFAULT); } else { if (explicitRoutingDevice != nullptr) { device = explicitRoutingDevice; @@ -1831,7 +1881,8 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, // know about it and is therefore considered "legacy" *inputType = API_INPUT_LEGACY; } else if (audio_is_remote_submix_device(device->type())) { - device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0")); + device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0"), + AUDIO_FORMAT_DEFAULT); *inputType = API_INPUT_MIX_CAPTURE; } else if (device->type() == AUDIO_DEVICE_IN_TELEPHONY_RX) { *inputType = API_INPUT_TELEPHONY_RX; @@ -2065,7 +2116,7 @@ status_t AudioPolicyManager::startInput(audio_port_handle_t portId) if (address != "") { setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, - address, "remote-submix"); + address, "remote-submix", AUDIO_FORMAT_DEFAULT); } } } @@ -2116,7 +2167,7 @@ status_t AudioPolicyManager::stopInput(audio_port_handle_t portId) if (address != "") { setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, - address, "remote-submix"); + address, "remote-submix", AUDIO_FORMAT_DEFAULT); } } resetInputDevice(input); @@ -2536,11 +2587,11 @@ status_t AudioPolicyManager::registerPolicyMixes(const Vector& mixes) if (mix.mMixType == MIX_TYPE_PLAYERS) { setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, - address.string(), "remote-submix"); + address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT); } else { setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, - address.string(), "remote-submix"); + address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT); } } else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) { String8 address = mix.mDeviceAddress; @@ -2614,13 +2665,13 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector mixes) AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, - address.string(), "remote-submix"); + address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT); } if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, - address.string(), "remote-submix"); + address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT); } rSubmixModule->removeOutputProfile(address); rSubmixModule->removeInputProfile(address); @@ -2664,7 +2715,8 @@ status_t AudioPolicyManager::setUidDeviceAffinities(uid_t uid, // reevaluate outputs for all given devices for (size_t i = 0; i < devices.size(); i++) { sp devDesc = mHwModules.getDeviceDescriptor( - devices[i].mType, devices[i].mAddress, String8()); + devices[i].mType, devices[i].mAddress, String8(), + AUDIO_FORMAT_DEFAULT); SortedVector outputs; if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, outputs) != NO_ERROR) { @@ -2685,7 +2737,8 @@ status_t AudioPolicyManager::removeUidDeviceAffinities(uid_t uid) { // reevaluate outputs for all found devices for (size_t i = 0; i < devices.size(); i++) { sp devDesc = mHwModules.getDeviceDescriptor( - devices[i].mType, devices[i].mAddress, String8()); + devices[i].mType, devices[i].mAddress, String8(), + AUDIO_FORMAT_DEFAULT); SortedVector outputs; if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, outputs) != NO_ERROR) { @@ -3442,7 +3495,8 @@ status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *so sp srcDevice = mAvailableInputDevices.getDevice(source->ext.device.type, - String8(source->ext.device.address)); + String8(source->ext.device.address), + AUDIO_FORMAT_DEFAULT); if (srcDevice == 0) { ALOGW("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type); return BAD_VALUE; @@ -3726,14 +3780,16 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), - name.c_str()); + name.c_str(), + AUDIO_FORMAT_DEFAULT); if (status != NO_ERROR) { continue; } status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), - name.c_str()); + name.c_str(), + AUDIO_FORMAT_DEFAULT); profileUpdated |= (status == NO_ERROR); } // FIXME: Why doing this for input HDMI devices if we don't augment their reported formats? @@ -3746,14 +3802,16 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), - name.c_str()); + name.c_str(), + AUDIO_FORMAT_DEFAULT); if (status != NO_ERROR) { continue; } status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI, AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(), - name.c_str()); + name.c_str(), + AUDIO_FORMAT_DEFAULT); profileUpdated |= (status == NO_ERROR); } @@ -4178,7 +4236,8 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp& d // first list already open outputs that can be routed to this device for (size_t i = 0; i < mOutputs.size(); i++) { desc = mOutputs.valueAt(i); - if (!desc->isDuplicated() && desc->supportsDevice(device)) { + if (!desc->isDuplicated() && desc->supportsDevice(device) + && desc->deviceSupportsEncodedFormats(deviceType)) { ALOGV("checkOutputsForDevice(): adding opened output %d on device %s", mOutputs.keyAt(i), device->toString().c_str()); outputs.add(mOutputs.keyAt(i)); @@ -4341,7 +4400,8 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp& d desc = mOutputs.valueAt(i); if (!desc->isDuplicated()) { // exact match on device - if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)) { + if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device) + && desc->deviceSupportsEncodedFormats(deviceType)) { outputs.add(mOutputs.keyAt(i)); } else if (!mAvailableOutputDevices.containsAtLeastOne(desc->supportedDevices())) { ALOGV("checkOutputsForDevice(): disconnecting adding output %d", @@ -4628,7 +4688,8 @@ SortedVector AudioPolicyManager::getOutputsForDevices( ALOGVV("output %zu isDuplicated=%d device=%s", i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices().toString().c_str()); - if (openOutputs.valueAt(i)->supportsAllDevices(devices)) { + if (openOutputs.valueAt(i)->supportsAllDevices(devices) + && openOutputs.valueAt(i)->deviceSupportsEncodedFormats(devices.types())) { ALOGVV("%s() found output %d", __func__, openOutputs.keyAt(i)); outputs.add(openOutputs.keyAt(i)); } @@ -4684,9 +4745,10 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) maxLatency = desc->latency(); } } - ALOGV("%s: strategy %d, moving from output %s to output %s", __func__, strategy, - (srcOutputs.isEmpty()? "none" : std::to_string(srcOutputs[0]).c_str()), - (dstOutputs.isEmpty()? "none" : std::to_string(dstOutputs[0]).c_str())); + ALOGV_IF(!(srcOutputs.isEmpty() || dstOutputs.isEmpty()), + "%s: strategy %d, moving from output %s to output %s", __func__, strategy, + std::to_string(srcOutputs[0]).c_str(), + std::to_string(dstOutputs[0]).c_str()); // mute strategy while moving tracks from one output to another for (audio_io_handle_t srcOut : srcOutputs) { sp desc = mPreviousOutputs.valueFor(srcOut); @@ -5404,9 +5466,10 @@ sp AudioPolicyManager::getDeviceForAttributes(const audio_attr if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX && strncmp(attributes.tags, "addr=", strlen("addr=")) == 0) { return mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, - String8(attributes.tags + strlen("addr="))); + String8(attributes.tags + strlen("addr=")), + AUDIO_FORMAT_DEFAULT); } - return mAvailableInputDevices.getDevice(device); + return mAvailableInputDevices.getDevice(device, String8(), AUDIO_FORMAT_DEFAULT); } float AudioPolicyManager::computeVolume(audio_stream_type_t stream, diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index e99de16493..4b42a3427e 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -97,12 +97,14 @@ public: virtual status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name); + const char *device_name, + audio_format_t encodedFormat); virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address); virtual status_t handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name); + const char *device_name, + audio_format_t encodedFormat); virtual void setPhoneState(audio_mode_t state); virtual void setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config); @@ -731,7 +733,8 @@ private: status_t setDeviceConnectionStateInt(audio_devices_t deviceType, audio_policy_dev_state_t state, const char *device_address, - const char *device_name); + const char *device_name, + audio_format_t encodedFormat); void updateMono(audio_io_handle_t output) { AudioParameter param; param.addInt(String8(AudioParameter::keyMonoOutput), (int)mMasterMono); diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 2c904d9ad7..09168f4e35 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -32,7 +32,8 @@ namespace android { status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { if (mAudioPolicyManager == NULL) { return NO_INIT; @@ -49,7 +50,7 @@ status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device, Mutex::Autolock _l(mLock); AutoCallerClear acc; return mAudioPolicyManager->setDeviceConnectionState(device, state, - device_address, device_name); + device_address, device_name, encodedFormat); } audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState( @@ -66,7 +67,8 @@ audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState( status_t AudioPolicyService::handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name) + const char *device_name, + audio_format_t encodedFormat) { if (mAudioPolicyManager == NULL) { return NO_INIT; @@ -79,7 +81,7 @@ status_t AudioPolicyService::handleDeviceConfigChange(audio_devices_t device, Mutex::Autolock _l(mLock); AutoCallerClear acc; return mAudioPolicyManager->handleDeviceConfigChange(device, device_address, - device_name); + device_name, encodedFormat); } status_t AudioPolicyService::setPhoneState(audio_mode_t state) diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index 959e757229..6ff973e1b7 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -61,13 +61,15 @@ public: virtual status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, - const char *device_name); + const char *device_name, + audio_format_t encodedFormat); virtual audio_policy_dev_state_t getDeviceConnectionState( audio_devices_t device, const char *device_address); virtual status_t handleDeviceConfigChange(audio_devices_t device, const char *device_address, - const char *device_name); + const char *device_name, + audio_format_t encodedFormat); virtual status_t setPhoneState(audio_mode_t state); virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config); virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);