diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp index c516d20f2b..2752ba646b 100644 --- a/media/libaudioclient/Android.bp +++ b/media/libaudioclient/Android.bp @@ -1,7 +1,15 @@ cc_library_headers { name: "libaudioclient_headers", vendor_available: true, - export_include_dirs: ["include"], + header_libs: [ + "libaudiofoundation_headers", + ], + export_include_dirs: [ + "include", + ], + export_header_lib_headers: [ + "libaudiofoundation_headers", + ], } cc_library_shared { @@ -63,6 +71,7 @@ cc_library_shared { "TrackPlayerBase.cpp", ], shared_libs: [ + "libaudiofoundation", "libaudioutils", "libaudiopolicy", "libaudiomanager", diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp index 46cfb684dd..6e9a7cf06d 100644 --- a/media/libaudioclient/IAudioFlinger.cpp +++ b/media/libaudioclient/IAudioFlinger.cpp @@ -392,20 +392,18 @@ public: virtual status_t openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, - audio_devices_t *devices, - const String8& address, + const sp& device, uint32_t *latencyMs, audio_output_flags_t flags) { - if (output == NULL || config == NULL || devices == NULL || latencyMs == NULL) { + if (output == nullptr || config == nullptr || device == nullptr || latencyMs == nullptr) { return BAD_VALUE; } Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32(module); data.write(config, sizeof(audio_config_t)); - data.writeInt32(*devices); - data.writeString8(address); + data.writeParcelable(*device); data.writeInt32((int32_t) flags); status_t status = remote()->transact(OPEN_OUTPUT, data, &reply); if (status != NO_ERROR) { @@ -420,7 +418,6 @@ public: *output = (audio_io_handle_t)reply.readInt32(); ALOGV("openOutput() returned output, %d", *output); reply.read(config, sizeof(audio_config_t)); - *devices = (audio_devices_t)reply.readInt32(); *latencyMs = reply.readInt32(); return NO_ERROR; } @@ -1198,19 +1195,21 @@ status_t BnAudioFlinger::onTransact( if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) { ALOGE("b/23905951"); } - audio_devices_t devices = (audio_devices_t)data.readInt32(); - String8 address(data.readString8()); + sp device = new DeviceDescriptorBase(AUDIO_DEVICE_NONE); + status_t status = NO_ERROR; + if ((status = data.readParcelable(device.get())) != NO_ERROR) { + reply->writeInt32((int32_t)status); + return NO_ERROR; + } audio_output_flags_t flags = (audio_output_flags_t) data.readInt32(); uint32_t latencyMs = 0; audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; - status_t status = openOutput(module, &output, &config, - &devices, address, &latencyMs, flags); + status = openOutput(module, &output, &config, device, &latencyMs, flags); ALOGV("OPEN_OUTPUT output, %d", output); reply->writeInt32((int32_t)status); if (status == NO_ERROR) { reply->writeInt32((int32_t)output); reply->write(&config, sizeof(audio_config_t)); - reply->writeInt32(devices); reply->writeInt32(latencyMs); } return NO_ERROR; diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h index b580a88be5..0a65857580 100644 --- a/media/libaudioclient/include/media/IAudioFlinger.h +++ b/media/libaudioclient/include/media/IAudioFlinger.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -416,8 +417,7 @@ public: virtual status_t openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, - audio_devices_t *devices, - const String8& address, + const sp& device, uint32_t *latencyMs, audio_output_flags_t flags) = 0; virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp index 1df0d16da6..edc06d2783 100644 --- a/media/libaudiofoundation/Android.bp +++ b/media/libaudiofoundation/Android.bp @@ -15,6 +15,7 @@ cc_library_headers { cc_library { name: "libaudiofoundation", vendor_available: true, + double_loadable: true, srcs: [ "AudioContainers.cpp", diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h index 8347c71763..05e68fa4e1 100644 --- a/media/libaudiofoundation/include/media/AudioContainers.h +++ b/media/libaudiofoundation/include/media/AudioContainers.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include #include @@ -78,6 +79,11 @@ static inline bool isSingleDeviceType(const DeviceTypeSet& deviceTypes, return deviceTypes.size() == 1 && p(*(deviceTypes.begin())); } +static inline bool areAllOfSameDeviceType(const DeviceTypeSet& deviceTypes, + std::function p) { + return std::all_of(deviceTypes.begin(), deviceTypes.end(), p); +} + static inline void resetDeviceTypes(DeviceTypeSet& deviceTypes, audio_devices_t typeToAdd) { deviceTypes.clear(); deviceTypes.insert(typeToAdd); diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp index b07f21d8b0..3d3a5eb739 100644 --- a/media/libaudiohal/impl/DeviceHalHidl.cpp +++ b/media/libaudiohal/impl/DeviceHalHidl.cpp @@ -229,14 +229,14 @@ status_t DeviceHalHidl::getInputBufferSize( status_t DeviceHalHidl::openOutputStream( audio_io_handle_t handle, - audio_devices_t devices, + audio_devices_t deviceType, audio_output_flags_t flags, struct audio_config *config, const char *address, sp *outStream) { if (mDevice == 0) return NO_INIT; DeviceAddress hidlDevice; - status_t status = deviceAddressFromHal(devices, address, &hidlDevice); + status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice); if (status != OK) return status; AudioConfig hidlConfig; HidlUtils::audioConfigFromHal(*config, &hidlConfig); diff --git a/media/libaudiohal/impl/DeviceHalLocal.cpp b/media/libaudiohal/impl/DeviceHalLocal.cpp index ee6825273a..dfbb6b2698 100644 --- a/media/libaudiohal/impl/DeviceHalLocal.cpp +++ b/media/libaudiohal/impl/DeviceHalLocal.cpp @@ -104,7 +104,7 @@ status_t DeviceHalLocal::getInputBufferSize( status_t DeviceHalLocal::openOutputStream( audio_io_handle_t handle, - audio_devices_t devices, + audio_devices_t deviceType, audio_output_flags_t flags, struct audio_config *config, const char *address, @@ -112,11 +112,11 @@ status_t DeviceHalLocal::openOutputStream( audio_stream_out_t *halStream; ALOGV("open_output_stream handle: %d devices: %x flags: %#x" "srate: %d format %#x channels %x address %s", - handle, devices, flags, + handle, deviceType, flags, config->sample_rate, config->format, config->channel_mask, address); int openResut = mDev->open_output_stream( - mDev, handle, devices, flags, config, &halStream, address); + mDev, handle, deviceType, flags, config, &halStream, address); if (openResut == OK) { *outStream = new StreamOutHalLocal(halStream, this); } diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h index e5652371e2..2200a7f1ce 100644 --- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h +++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h @@ -69,7 +69,7 @@ class DeviceHalInterface : public RefBase // by releasing all references to the returned object. virtual status_t openOutputStream( audio_io_handle_t handle, - audio_devices_t devices, + audio_devices_t deviceType, audio_output_flags_t flags, struct audio_config *config, const char *address, diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp index d50a556082..de8c7e79c7 100644 --- a/services/audioflinger/Android.bp +++ b/services/audioflinger/Android.bp @@ -34,6 +34,7 @@ cc_library_shared { ], shared_libs: [ + "libaudiofoundation", "libaudiohal", "libaudioprocessing", "libaudiospdif", diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 65261dab80..eba0b20613 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -381,7 +381,7 @@ static const char * const audio_interfaces[] = { AudioHwDevice* AudioFlinger::findSuitableHwDev_l( audio_module_handle_t module, - audio_devices_t devices) + audio_devices_t deviceType) { // if module is 0, the request comes from an old policy manager and we should load // well known modules @@ -396,7 +396,7 @@ AudioHwDevice* AudioFlinger::findSuitableHwDev_l( sp dev = audioHwDevice->hwDevice(); uint32_t supportedDevices; if (dev->getSupportedDevices(&supportedDevices) == OK && - (supportedDevices & devices) == devices) { + (supportedDevices & deviceType) == deviceType) { return audioHwDevice; } } @@ -2304,13 +2304,13 @@ void AudioFlinger::setAudioHwSyncForSession_l(PlaybackThread *thread, audio_sess sp AudioFlinger::openOutput_l(audio_module_handle_t module, - audio_io_handle_t *output, - audio_config_t *config, - audio_devices_t devices, - const String8& address, - audio_output_flags_t flags) + audio_io_handle_t *output, + audio_config_t *config, + audio_devices_t deviceType, + const String8& address, + audio_output_flags_t flags) { - AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices); + AudioHwDevice *outHwDev = findSuitableHwDev_l(module, deviceType); if (outHwDev == NULL) { return 0; } @@ -2351,7 +2351,7 @@ sp AudioFlinger::openOutput_l(audio_module_handle_t mo status_t status = outHwDev->openOutputStream( &outputStream, *output, - devices, + deviceType, flags, config, address.string()); @@ -2362,7 +2362,7 @@ sp AudioFlinger::openOutput_l(audio_module_handle_t mo if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) { sp thread = new MmapPlaybackThread(this, *output, outHwDev, outputStream, - devices, AUDIO_DEVICE_NONE, mSystemReady); + deviceType, AUDIO_DEVICE_NONE, mSystemReady); mMmapThreads.add(*output, thread); ALOGV("openOutput_l() created mmap playback thread: ID %d thread %p", *output, thread.get()); @@ -2370,17 +2370,18 @@ sp AudioFlinger::openOutput_l(audio_module_handle_t mo } else { sp thread; if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) { - thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady); + thread = new OffloadThread(this, outputStream, *output, deviceType, mSystemReady); ALOGV("openOutput_l() created offload output: ID %d thread %p", *output, thread.get()); } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) || !isValidPcmSinkFormat(config->format) || !isValidPcmSinkChannelMask(config->channel_mask)) { - thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady); + thread = new DirectOutputThread( + this, outputStream, *output, deviceType, mSystemReady); ALOGV("openOutput_l() created direct output: ID %d thread %p", *output, thread.get()); } else { - thread = new MixerThread(this, outputStream, *output, devices, mSystemReady); + thread = new MixerThread(this, outputStream, *output, deviceType, mSystemReady); ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread.get()); } @@ -2396,27 +2397,29 @@ sp AudioFlinger::openOutput_l(audio_module_handle_t mo status_t AudioFlinger::openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, - audio_devices_t *devices, - const String8& address, + const sp& device, uint32_t *latencyMs, audio_output_flags_t flags) { - ALOGI("openOutput() this %p, module %d Device %#x, SamplingRate %d, Format %#08x, " + ALOGI("openOutput() this %p, module %d Device %s, SamplingRate %d, Format %#08x, " "Channels %#x, flags %#x", this, module, - (devices != NULL) ? *devices : 0, + device->toString().c_str(), config->sample_rate, config->format, config->channel_mask, flags); - if (devices == NULL || *devices == AUDIO_DEVICE_NONE) { + audio_devices_t deviceType = device->type(); + const String8 address = String8(device->address().c_str()); + + if (deviceType == AUDIO_DEVICE_NONE) { return BAD_VALUE; } Mutex::Autolock _l(mLock); - sp thread = openOutput_l(module, output, config, *devices, address, flags); + sp thread = openOutput_l(module, output, config, deviceType, address, flags); if (thread != 0) { if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) { PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index d2de5fe6fd..65be06d0de 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -175,8 +175,7 @@ public: virtual status_t openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, - audio_devices_t *devices, - const String8& address, + const sp& device, uint32_t *latencyMs, audio_output_flags_t flags); @@ -372,7 +371,7 @@ private: virtual void onFirstRef(); AudioHwDevice* findSuitableHwDev_l(audio_module_handle_t module, - audio_devices_t devices); + audio_devices_t deviceType); // Set kEnableExtendedChannels to true to enable greater than stereo output // for the MixerThread and device sink. Number of channels allowed is @@ -678,11 +677,11 @@ using effect_buffer_t = int16_t; audio_devices_t outputDevice, const String8& outputDeviceAddress); sp openOutput_l(audio_module_handle_t module, - audio_io_handle_t *output, - audio_config_t *config, - audio_devices_t devices, - const String8& address, - audio_output_flags_t flags); + audio_io_handle_t *output, + audio_config_t *config, + audio_devices_t deviceType, + const String8& address, + audio_output_flags_t flags); void closeOutputFinish(const sp& thread); void closeInputFinish(const sp& thread); diff --git a/services/audioflinger/AudioHwDevice.cpp b/services/audioflinger/AudioHwDevice.cpp index b109d061a6..dda164c281 100644 --- a/services/audioflinger/AudioHwDevice.cpp +++ b/services/audioflinger/AudioHwDevice.cpp @@ -34,7 +34,7 @@ namespace android { status_t AudioHwDevice::openOutputStream( AudioStreamOut **ppStreamOut, audio_io_handle_t handle, - audio_devices_t devices, + audio_devices_t deviceType, audio_output_flags_t flags, struct audio_config *config, const char *address) @@ -50,7 +50,7 @@ status_t AudioHwDevice::openOutputStream( config->sample_rate, config->format, config->channel_mask); - status_t status = outputStream->open(handle, devices, config, address); + status_t status = outputStream->open(handle, deviceType, config, address); if (status != NO_ERROR) { delete outputStream; @@ -75,7 +75,7 @@ status_t AudioHwDevice::openOutputStream( if (wrapperNeeded) { if (SPDIFEncoder::isFormatSupported(originalConfig.format)) { outputStream = new SpdifStreamOut(this, flags, originalConfig.format); - status = outputStream->open(handle, devices, &originalConfig, address); + status = outputStream->open(handle, deviceType, &originalConfig, address); if (status != NO_ERROR) { ALOGE("ERROR - openOutputStream(), SPDIF open returned %d", status); diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h index d4299b09e0..6709d17a25 100644 --- a/services/audioflinger/AudioHwDevice.h +++ b/services/audioflinger/AudioHwDevice.h @@ -76,7 +76,7 @@ public: status_t openOutputStream( AudioStreamOut **ppStreamOut, audio_io_handle_t handle, - audio_devices_t devices, + audio_devices_t deviceType, audio_output_flags_t flags, struct audio_config *config, const char *address); diff --git a/services/audioflinger/AudioStreamOut.cpp b/services/audioflinger/AudioStreamOut.cpp index a60a5f2272..d13cb8f2c9 100644 --- a/services/audioflinger/AudioStreamOut.cpp +++ b/services/audioflinger/AudioStreamOut.cpp @@ -118,7 +118,7 @@ status_t AudioStreamOut::getPresentationPosition(uint64_t *frames, struct timesp status_t AudioStreamOut::open( audio_io_handle_t handle, - audio_devices_t devices, + audio_devices_t deviceType, struct audio_config *config, const char *address) { @@ -130,7 +130,7 @@ status_t AudioStreamOut::open( int status = hwDev()->openOutputStream( handle, - devices, + deviceType, customFlags, config, address, @@ -152,7 +152,7 @@ status_t AudioStreamOut::open( status = hwDev()->openOutputStream( handle, - devices, + deviceType, customFlags, &customConfig, address, diff --git a/services/audioflinger/AudioStreamOut.h b/services/audioflinger/AudioStreamOut.h index b16b1af635..16fbcf251a 100644 --- a/services/audioflinger/AudioStreamOut.h +++ b/services/audioflinger/AudioStreamOut.h @@ -47,7 +47,7 @@ public: virtual status_t open( audio_io_handle_t handle, - audio_devices_t devices, + audio_devices_t deviceType, struct audio_config *config, const char *address); diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index 35126ad7ab..0d3e61444a 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -19,6 +19,7 @@ #include #include +#include #include namespace android { @@ -296,8 +297,7 @@ public: virtual status_t openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, - audio_devices_t *devices, - const String8& address, + const sp& device, uint32_t *latencyMs, audio_output_flags_t flags) = 0; // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by diff --git a/services/audiopolicy/common/include/Volume.h b/services/audiopolicy/common/include/Volume.h index c3a02f9d20..7c8ce83a7c 100644 --- a/services/audiopolicy/common/include/Volume.h +++ b/services/audiopolicy/common/include/Volume.h @@ -22,6 +22,8 @@ #include #include +#include "policy.h" + namespace android { /** @@ -85,43 +87,14 @@ public: */ static audio_devices_t getDeviceForVolume(const android::DeviceTypeSet& deviceTypes) { - audio_devices_t deviceType = AUDIO_DEVICE_NONE; if (deviceTypes.empty()) { // this happens when forcing a route update and no track is active on an output. // In this case the returned category is not important. - deviceType = AUDIO_DEVICE_OUT_SPEAKER; - } else if (deviceTypes.size() > 1) { - // Multiple device selection is either: - // - speaker + one other device: give priority to speaker in this case. - // - one A2DP device + another device: happens with duplicated output. In this case - // retain the device on the A2DP output as the other must not correspond to an active - // selection if not the speaker. - // - HDMI-CEC system audio mode only output: give priority to available item in order. - if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER) != 0) { - deviceType = AUDIO_DEVICE_OUT_SPEAKER; - } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER_SAFE) != 0) { - deviceType = AUDIO_DEVICE_OUT_SPEAKER_SAFE; - } else if (deviceTypes.count(AUDIO_DEVICE_OUT_HDMI_ARC) != 0) { - deviceType = AUDIO_DEVICE_OUT_HDMI_ARC; - } else if (deviceTypes.count(AUDIO_DEVICE_OUT_AUX_LINE) != 0) { - deviceType = AUDIO_DEVICE_OUT_AUX_LINE; - } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPDIF) != 0) { - deviceType = AUDIO_DEVICE_OUT_SPDIF; - } else { - std::vector a2dpDevices = android::Intersection( - deviceTypes, android::getAudioDeviceOutAllA2dpSet()); - if (a2dpDevices.size() > 1) { - ALOGW("getDeviceForVolume() invalid device combination: %s", - android::dumpDeviceTypes(deviceTypes).c_str()); - } - if (!a2dpDevices.empty()) { - deviceType = a2dpDevices[0]; - } - } - } else { - deviceType = *(deviceTypes.begin()); + return AUDIO_DEVICE_OUT_SPEAKER; } + audio_devices_t deviceType = apm_extract_one_audio_device(deviceTypes); + /*SPEAKER_SAFE is an alias of SPEAKER for purposes of volume control*/ if (deviceType == AUDIO_DEVICE_OUT_SPEAKER_SAFE) { deviceType = AUDIO_DEVICE_OUT_SPEAKER; diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h index 630efc166d..0537365ae2 100644 --- a/services/audiopolicy/common/include/policy.h +++ b/services/audiopolicy/common/include/policy.h @@ -19,6 +19,8 @@ #include #include +#include + namespace android { using StreamTypeVector = std::vector; @@ -199,3 +201,43 @@ static inline bool hasVoiceStream(const android::StreamTypeVector &streams) { return hasStream(streams, AUDIO_STREAM_VOICE_CALL); } + +/** + * @brief extract one device relevant from multiple device selection + * @param deviceTypes collection of audio device type + * @return the device type that is selected + */ +static inline audio_devices_t apm_extract_one_audio_device( + const android::DeviceTypeSet& deviceTypes) { + if (deviceTypes.empty()) { + return AUDIO_DEVICE_NONE; + } else if (deviceTypes.size() == 1) { + return *(deviceTypes.begin()); + } else { + // Multiple device selection is either: + // - speaker + one other device: give priority to speaker in this case. + // - one A2DP device + another device: happens with duplicated output. In this case + // retain the device on the A2DP output as the other must not correspond to an active + // selection if not the speaker. + // - HDMI-CEC system audio mode only output: give priority to available item in order. + if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER) != 0) { + return AUDIO_DEVICE_OUT_SPEAKER; + } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER_SAFE) != 0) { + return AUDIO_DEVICE_OUT_SPEAKER_SAFE; + } else if (deviceTypes.count(AUDIO_DEVICE_OUT_HDMI_ARC) != 0) { + return AUDIO_DEVICE_OUT_HDMI_ARC; + } else if (deviceTypes.count(AUDIO_DEVICE_OUT_AUX_LINE) != 0) { + return AUDIO_DEVICE_OUT_AUX_LINE; + } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPDIF) != 0) { + return AUDIO_DEVICE_OUT_SPDIF; + } else { + std::vector a2dpDevices = android::Intersection( + deviceTypes, android::getAudioDeviceOutAllA2dpSet()); + if (a2dpDevices.empty() || a2dpDevices.size() > 1) { + ALOGW("%s invalid device combination: %s", + __func__, android::dumpDeviceTypes(deviceTypes).c_str()); + } + return a2dpDevices.empty() ? AUDIO_DEVICE_NONE : a2dpDevices[0]; + } + } +} \ No newline at end of file diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h index 158215d98c..7faf90e892 100644 --- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h @@ -130,6 +130,14 @@ public: DeviceVector getFirstDevicesFromTypes(std::vector orderedTypes) const; sp getFirstExistingDevice(std::vector orderedTypes) const; + // Return device descriptor that is used to open an input/output stream. + // Null pointer will be returned if + // 1) this collection is empty + // 2) the device descriptors are not the same category(input or output) + // 3) there are more than one device type for input case + // 4) the combination of all devices is invalid for selection + sp getDeviceForOpening() const; + // If there are devices with the given type and the devices to add is not empty, // remove all the devices with the given type and add all the devices to add. void replaceDevicesByType(audio_devices_t typeToRemove, const DeviceVector &devicesToAdd); diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index 4ff69eec47..dd516581c2 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -467,8 +467,11 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *config, audio_io_handle_t *output) { mDevices = devices; - const String8& address = devices.getFirstValidAddress(); - DeviceTypeSet deviceTypes = devices.types(); + sp device = devices.getDeviceForOpening(); + LOG_ALWAYS_FATAL_IF(device == nullptr, + "%s failed to get device descriptor for opening " + "with the requested devices, all device types: %s", + __func__, dumpDeviceTypes(devices.types()).c_str()); audio_config_t lConfig; if (config == nullptr) { @@ -500,25 +503,19 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *config, ALOGV("opening output for device %s profile %p name %s", mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str()); - // FIXME: Stop using device types as bit mask when the interface updated. - audio_devices_t deviceType = deviceTypesToBitMask(deviceTypes); status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(), output, &lConfig, - &deviceType, - address, + device, &mLatency, mFlags); - deviceTypes = deviceTypesFromBitMask(deviceType); - LOG_ALWAYS_FATAL_IF(mDevices.types() != deviceTypes, - "%s openOutput returned device %s when given device %s", - __FUNCTION__, dumpDeviceTypes(mDevices.types()).c_str(), - dumpDeviceTypes(deviceTypes).c_str()); if (status == NO_ERROR) { LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE, - "%s openOutput returned output handle %d for device %s", - __FUNCTION__, *output, dumpDeviceTypes(deviceTypes).c_str()); + "%s openOutput returned output handle %d for device %s, " + "selected device %s for opening", + __FUNCTION__, *output, devices.toString().c_str(), + device->toString().c_str()); mSamplingRate = lConfig.sample_rate; mChannelMask = lConfig.channel_mask; mFormat = lConfig.format; diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp index 4e8c01ce3e..05870415a1 100644 --- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp @@ -328,6 +328,24 @@ sp DeviceVector::getFirstExistingDevice( return device; } +sp DeviceVector::getDeviceForOpening() const +{ + if (isEmpty()) { + // Return nullptr if this collection is empty. + return nullptr; + } else if (areAllOfSameDeviceType(types(), audio_is_input_device)) { + // For input case, return the first one when there is only one device. + return size() > 1 ? nullptr : *begin(); + } else if (areAllOfSameDeviceType(types(), audio_is_output_device)) { + // For output case, return the device descriptor according to apm strategy. + audio_devices_t deviceType = apm_extract_one_audio_device(types()); + return deviceType == AUDIO_DEVICE_NONE ? nullptr : + getDevice(deviceType, String8(""), AUDIO_FORMAT_DEFAULT); + } + // Return null pointer if the devices are not all input/output device. + return nullptr; +} + void DeviceVector::replaceDevicesByType( audio_devices_t typeToRemove, const DeviceVector &devicesToAdd) { DeviceVector devicesToRemove = getDevicesFromType(typeToRemove); diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp index d51cc6ecc6..6de0c80e7f 100644 --- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp @@ -39,8 +39,7 @@ audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, - audio_devices_t *devices, - const String8& address, + const sp& device, uint32_t *latencyMs, audio_output_flags_t flags) { @@ -49,7 +48,7 @@ status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t ALOGW("%s: could not get AudioFlinger", __func__); return PERMISSION_DENIED; } - return af->openOutput(module, output, config, devices, address, latencyMs, flags); + return af->openOutput(module, output, config, device, latencyMs, flags); } audio_io_handle_t AudioPolicyService::AudioPolicyClient::openDuplicateOutput( diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index 939df2c64f..175fed4f65 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -622,8 +622,7 @@ private: virtual status_t openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *config, - audio_devices_t *devices, - const String8& address, + const sp& device, uint32_t *latencyMs, audio_output_flags_t flags); // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h index afe6f2071b..c2a92d7270 100644 --- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h +++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h @@ -34,8 +34,7 @@ public: status_t openOutput(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t * /*config*/, - audio_devices_t * /*devices*/, - const String8 & /*address*/, + const sp& /*device*/, uint32_t * /*latencyMs*/, audio_output_flags_t /*flags*/) override { if (module >= mNextModuleHandle) { diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h index e4c64e511f..b92a2e681f 100644 --- a/services/audiopolicy/tests/AudioPolicyTestClient.h +++ b/services/audiopolicy/tests/AudioPolicyTestClient.h @@ -31,8 +31,7 @@ public: status_t openOutput(audio_module_handle_t /*module*/, audio_io_handle_t* /*output*/, audio_config_t* /*config*/, - audio_devices_t* /*devices*/, - const String8& /*address*/, + const sp& /*device*/, uint32_t* /*latencyMs*/, audio_output_flags_t /*flags*/) override { return NO_INIT; } audio_io_handle_t openDuplicateOutput(audio_io_handle_t /*output1*/,