mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
audio: Refactor configuration population am: a92039ac48
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2886670 Change-Id: I3594561197a36aa377816458ab1a324ee61410da Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -93,32 +93,6 @@ bool hasDynamicProfilesOnly(const std::vector<AudioProfile>& profiles) {
|
||||
return std::all_of(profiles.begin(), profiles.end(), isDynamicProfile);
|
||||
}
|
||||
|
||||
// Note: does not assign an ID to the config.
|
||||
bool generateDefaultPortConfig(const AudioPort& port, AudioPortConfig* config) {
|
||||
const bool allowDynamicConfig = port.ext.getTag() == AudioPortExt::device;
|
||||
*config = {};
|
||||
config->portId = port.id;
|
||||
for (const auto& profile : port.profiles) {
|
||||
if (isDynamicProfile(profile)) continue;
|
||||
config->format = profile.format;
|
||||
config->channelMask = *profile.channelMasks.begin();
|
||||
config->sampleRate = Int{.value = *profile.sampleRates.begin()};
|
||||
config->flags = port.flags;
|
||||
config->ext = port.ext;
|
||||
return true;
|
||||
}
|
||||
if (allowDynamicConfig) {
|
||||
config->format = AudioFormatDescription{};
|
||||
config->channelMask = AudioChannelLayout{};
|
||||
config->sampleRate = Int{.value = 0};
|
||||
config->flags = port.flags;
|
||||
config->ext = port.ext;
|
||||
return true;
|
||||
}
|
||||
LOG(ERROR) << __func__ << ": port " << port.id << " only has dynamic profiles";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findAudioProfile(const AudioPort& port, const AudioFormatDescription& format,
|
||||
AudioProfile* profile) {
|
||||
if (auto profilesIt =
|
||||
@@ -204,10 +178,11 @@ ndk::ScopedAStatus Module::createStreamContext(
|
||||
}
|
||||
auto& configs = getConfig().portConfigs;
|
||||
auto portConfigIt = findById<AudioPortConfig>(configs, in_portConfigId);
|
||||
const int32_t nominalLatencyMs = getNominalLatencyMs(*portConfigIt);
|
||||
// Since this is a private method, it is assumed that
|
||||
// validity of the portConfigId has already been checked.
|
||||
const int32_t minimumStreamBufferSizeFrames = calculateBufferSizeFrames(
|
||||
getNominalLatencyMs(*portConfigIt), portConfigIt->sampleRate.value().value);
|
||||
const int32_t minimumStreamBufferSizeFrames =
|
||||
calculateBufferSizeFrames(nominalLatencyMs, portConfigIt->sampleRate.value().value);
|
||||
if (in_bufferSizeFrames < minimumStreamBufferSizeFrames) {
|
||||
LOG(ERROR) << __func__ << ": insufficient buffer size " << in_bufferSizeFrames
|
||||
<< ", must be at least " << minimumStreamBufferSizeFrames;
|
||||
@@ -241,7 +216,7 @@ ndk::ScopedAStatus Module::createStreamContext(
|
||||
std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
|
||||
std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
|
||||
portConfigIt->format.value(), portConfigIt->channelMask.value(),
|
||||
portConfigIt->sampleRate.value().value, flags, getNominalLatencyMs(*portConfigIt),
|
||||
portConfigIt->sampleRate.value().value, flags, nominalLatencyMs,
|
||||
portConfigIt->ext.get<AudioPortExt::mix>().handle,
|
||||
std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
|
||||
asyncCallback, outEventCallback,
|
||||
@@ -328,6 +303,29 @@ ndk::ScopedAStatus Module::findPortIdForNewStream(int32_t in_portConfigId, Audio
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
bool Module::generateDefaultPortConfig(const AudioPort& port, AudioPortConfig* config) {
|
||||
const bool allowDynamicConfig = port.ext.getTag() == AudioPortExt::device;
|
||||
for (const auto& profile : port.profiles) {
|
||||
if (isDynamicProfile(profile)) continue;
|
||||
config->format = profile.format;
|
||||
config->channelMask = *profile.channelMasks.begin();
|
||||
config->sampleRate = Int{.value = *profile.sampleRates.begin()};
|
||||
config->flags = port.flags;
|
||||
config->ext = port.ext;
|
||||
return true;
|
||||
}
|
||||
if (allowDynamicConfig) {
|
||||
config->format = AudioFormatDescription{};
|
||||
config->channelMask = AudioChannelLayout{};
|
||||
config->sampleRate = Int{.value = 0};
|
||||
config->flags = port.flags;
|
||||
config->ext = port.ext;
|
||||
return true;
|
||||
}
|
||||
LOG(ERROR) << __func__ << ": port " << port.id << " only has dynamic profiles";
|
||||
return false;
|
||||
}
|
||||
|
||||
void Module::populateConnectedProfiles() {
|
||||
Configuration& config = getConfig();
|
||||
for (const AudioPort& port : config.ports) {
|
||||
@@ -617,10 +615,11 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA
|
||||
|
||||
std::vector<AudioRoute*> routesToMixPorts = getAudioRoutesForAudioPortImpl(templateId);
|
||||
std::set<int32_t> routableMixPortIds = getRoutableAudioPortIds(templateId, &routesToMixPorts);
|
||||
const int32_t nextPortId = getConfig().nextPortId++;
|
||||
if (!mDebug.simulateDeviceConnections) {
|
||||
// Even if the device port has static profiles, the HAL module might need to update
|
||||
// them, or abort the connection process.
|
||||
RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort));
|
||||
RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort, nextPortId));
|
||||
} else if (hasDynamicProfilesOnly(connectedPort.profiles)) {
|
||||
auto& connectedProfiles = getConfig().connectedProfiles;
|
||||
if (auto connectedProfilesIt = connectedProfiles.find(templateId);
|
||||
@@ -644,7 +643,7 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA
|
||||
}
|
||||
}
|
||||
|
||||
connectedPort.id = getConfig().nextPortId++;
|
||||
connectedPort.id = nextPortId;
|
||||
auto [connectedPortsIt, _] =
|
||||
mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::set<int32_t>()));
|
||||
LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
|
||||
@@ -1035,6 +1034,18 @@ ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPa
|
||||
|
||||
ndk::ScopedAStatus Module::setAudioPortConfig(const AudioPortConfig& in_requested,
|
||||
AudioPortConfig* out_suggested, bool* _aidl_return) {
|
||||
auto generate = [this](const AudioPort& port, AudioPortConfig* config) {
|
||||
return generateDefaultPortConfig(port, config);
|
||||
};
|
||||
return setAudioPortConfigImpl(in_requested, generate, out_suggested, _aidl_return);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::setAudioPortConfigImpl(
|
||||
const AudioPortConfig& in_requested,
|
||||
const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port,
|
||||
::aidl::android::media::audio::common::AudioPortConfig* config)>&
|
||||
fillPortConfig,
|
||||
AudioPortConfig* out_suggested, bool* applied) {
|
||||
LOG(DEBUG) << __func__ << ": requested " << in_requested.toString();
|
||||
auto& configs = getConfig().portConfigs;
|
||||
auto existing = configs.end();
|
||||
@@ -1063,7 +1074,8 @@ ndk::ScopedAStatus Module::setAudioPortConfig(const AudioPortConfig& in_requeste
|
||||
*out_suggested = *existing;
|
||||
} else {
|
||||
AudioPortConfig newConfig;
|
||||
if (generateDefaultPortConfig(*portIt, &newConfig)) {
|
||||
newConfig.portId = portIt->id;
|
||||
if (fillPortConfig(*portIt, &newConfig)) {
|
||||
*out_suggested = newConfig;
|
||||
} else {
|
||||
LOG(ERROR) << __func__ << ": unable generate a default config for port " << portId;
|
||||
@@ -1168,17 +1180,17 @@ ndk::ScopedAStatus Module::setAudioPortConfig(const AudioPortConfig& in_requeste
|
||||
if (existing == configs.end() && requestedIsValid && requestedIsFullySpecified) {
|
||||
out_suggested->id = getConfig().nextPortId++;
|
||||
configs.push_back(*out_suggested);
|
||||
*_aidl_return = true;
|
||||
*applied = true;
|
||||
LOG(DEBUG) << __func__ << ": created new port config " << out_suggested->toString();
|
||||
} else if (existing != configs.end() && requestedIsValid) {
|
||||
*existing = *out_suggested;
|
||||
*_aidl_return = true;
|
||||
*applied = true;
|
||||
LOG(DEBUG) << __func__ << ": updated port config " << out_suggested->toString();
|
||||
} else {
|
||||
LOG(DEBUG) << __func__ << ": not applied; existing config ? " << (existing != configs.end())
|
||||
<< "; requested is valid? " << requestedIsValid << ", fully specified? "
|
||||
<< requestedIsFullySpecified;
|
||||
*_aidl_return = false;
|
||||
*applied = false;
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
@@ -1530,7 +1542,7 @@ bool Module::isMmapSupported() {
|
||||
return mIsMmapSupported.value();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort) {
|
||||
ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
|
||||
if (audioPort->ext.getTag() != AudioPortExt::device) {
|
||||
LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
|
||||
@@ -34,7 +34,7 @@ using aidl::android::media::audio::common::AudioProfile;
|
||||
|
||||
namespace aidl::android::hardware::audio::core {
|
||||
|
||||
ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort) {
|
||||
ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
|
||||
auto deviceProfile = alsa::getDeviceProfile(*audioPort);
|
||||
if (!deviceProfile.has_value()) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
|
||||
@@ -109,7 +109,7 @@ ndk::ScopedAStatus ModuleBluetooth::createOutputStream(
|
||||
offloadInfo, getBtProfileManagerHandles());
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort) {
|
||||
ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
|
||||
if (audioPort->ext.getTag() != AudioPortExt::device) {
|
||||
LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -188,7 +189,7 @@ class Module : public BnModule {
|
||||
// If the module is unable to populate the connected device port correctly, the returned error
|
||||
// code must correspond to the errors of `IModule.connectedExternalDevice` method.
|
||||
virtual ndk::ScopedAStatus populateConnectedDevicePort(
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort);
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort, int32_t nextPortId);
|
||||
// If the module finds that the patch endpoints configurations are not matched, the returned
|
||||
// error code must correspond to the errors of `IModule.setAudioPatch` method.
|
||||
virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
|
||||
@@ -210,6 +211,7 @@ class Module : public BnModule {
|
||||
const int32_t rawSizeFrames =
|
||||
aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs,
|
||||
sampleRateHz);
|
||||
if (latencyMs >= 5) return rawSizeFrames;
|
||||
int32_t powerOf2 = 1;
|
||||
while (powerOf2 < rawSizeFrames) powerOf2 <<= 1;
|
||||
return powerOf2;
|
||||
@@ -227,12 +229,16 @@ class Module : public BnModule {
|
||||
std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId);
|
||||
ndk::ScopedAStatus findPortIdForNewStream(
|
||||
int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port);
|
||||
// Note: does not assign an ID to the config.
|
||||
bool generateDefaultPortConfig(const ::aidl::android::media::audio::common::AudioPort& port,
|
||||
::aidl::android::media::audio::common::AudioPortConfig* config);
|
||||
std::vector<AudioRoute*> getAudioRoutesForAudioPortImpl(int32_t portId);
|
||||
Configuration& getConfig();
|
||||
const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; }
|
||||
bool getMasterMute() const { return mMasterMute; }
|
||||
bool getMasterVolume() const { return mMasterVolume; }
|
||||
bool getMicMute() const { return mMicMute; }
|
||||
const ModuleDebug& getModuleDebug() const { return mDebug; }
|
||||
const Patches& getPatches() const { return mPatches; }
|
||||
std::set<int32_t> getRoutableAudioPortIds(int32_t portId,
|
||||
std::vector<AudioRoute*>* routes = nullptr);
|
||||
@@ -243,6 +249,12 @@ class Module : public BnModule {
|
||||
template <typename C>
|
||||
std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds);
|
||||
void registerPatch(const AudioPatch& patch);
|
||||
ndk::ScopedAStatus setAudioPortConfigImpl(
|
||||
const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
|
||||
const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port,
|
||||
::aidl::android::media::audio::common::AudioPortConfig*
|
||||
config)>& fillPortConfig,
|
||||
::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied);
|
||||
ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch,
|
||||
const AudioPatch& newPatch);
|
||||
};
|
||||
|
||||
@@ -33,7 +33,8 @@ class ModuleAlsa : public Module {
|
||||
protected:
|
||||
// Extension methods of 'Module'.
|
||||
ndk::ScopedAStatus populateConnectedDevicePort(
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort) override;
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort,
|
||||
int32_t nextPortId) override;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::audio::core
|
||||
|
||||
@@ -52,7 +52,8 @@ class ModuleBluetooth final : public Module {
|
||||
offloadInfo,
|
||||
std::shared_ptr<StreamOut>* result) override;
|
||||
ndk::ScopedAStatus populateConnectedDevicePort(
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort) override;
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort,
|
||||
int32_t nextPortId) override;
|
||||
ndk::ScopedAStatus onMasterMuteChanged(bool mute) override;
|
||||
ndk::ScopedAStatus onMasterVolumeChanged(float volume) override;
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ class ModuleRemoteSubmix : public Module {
|
||||
offloadInfo,
|
||||
std::shared_ptr<StreamOut>* result) override;
|
||||
ndk::ScopedAStatus populateConnectedDevicePort(
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort) override;
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort,
|
||||
int32_t nextPortId) override;
|
||||
ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
|
||||
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
|
||||
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
|
||||
|
||||
@@ -44,7 +44,8 @@ class ModuleUsb final : public ModuleAlsa {
|
||||
offloadInfo,
|
||||
std::shared_ptr<StreamOut>* result) override;
|
||||
ndk::ScopedAStatus populateConnectedDevicePort(
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort) override;
|
||||
::aidl::android::media::audio::common::AudioPort* audioPort,
|
||||
int32_t nextPortId) override;
|
||||
ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
|
||||
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
|
||||
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
|
||||
|
||||
@@ -67,7 +67,7 @@ ndk::ScopedAStatus ModuleRemoteSubmix::createOutputStream(
|
||||
offloadInfo);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort) {
|
||||
ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
|
||||
// Find the corresponding mix port and copy its profiles.
|
||||
// At this moment, the port has the same ID as the template port, see connectExternalDevice.
|
||||
std::vector<AudioRoute*> routes = getAudioRoutesForAudioPortImpl(audioPort->id);
|
||||
|
||||
@@ -87,12 +87,13 @@ ndk::ScopedAStatus ModuleUsb::createOutputStream(StreamContext&& context,
|
||||
offloadInfo);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort) {
|
||||
ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort,
|
||||
int32_t nextPortId) {
|
||||
if (!isUsbDevicePort(*audioPort)) {
|
||||
LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a usb device port";
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
return ModuleAlsa::populateConnectedDevicePort(audioPort);
|
||||
return ModuleAlsa::populateConnectedDevicePort(audioPort, nextPortId);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus ModuleUsb::checkAudioPatchEndpointsMatch(
|
||||
|
||||
Reference in New Issue
Block a user