Make audio port in policy not derive from audio port base
This patch aims to make the structure for libaudiofoundation and policy
stuff simpler, including:
1. Make AudioPortBase as AudioPort in libaudiofoundation. Create
PolicyAudioPort that contains policy related stuff, which is used by
audiopolicy.
2. Make AudioPortConfigBase as AudioPortConfig in libaudiofoundation.
Create PolicyAudioPortConfig that contains policy related stuff.
3. DeviceDescriptor derives from AudioPort, AudioPortConfig, PolicyAudioPort
and PolicyAudioPortConfig. IOProfile derives from AudioPort,
PolicyAudioPort. AudioInputDescriptor/AudioOutputDescriptor derives from
AudioPortConfig, PolicyAudioPortConfig.
Test: atest AudioTrackTest, AudioRecordTest, AudioManagerTest
Test: atest audiopolicy_tests, AudioHostTest
Test: audio smoke test
Bug: 135621476
Change-Id: I40299d95dda3b3fc0ea88b079f2fe38d8f7e5b31
Merged-In: I40299d95dda3b3fc0ea88b079f2fe38d8f7e5b31
diff --git a/media/libaudiofoundation/AudioPortBase.cpp b/media/libaudiofoundation/AudioPortBase.cpp
index 8b41be7..b73f8bf 100644
--- a/media/libaudiofoundation/AudioPortBase.cpp
+++ b/media/libaudiofoundation/AudioPortBase.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "AudioPortBase"
#include <algorithm>
@@ -22,7 +23,22 @@
namespace android {
-void AudioPortBase::toAudioPort(struct audio_port *port) const {
+void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
+{
+ for (const auto& profileToImport : port->mProfiles) {
+ // Import only valid port, i.e. valid format, non empty rates and channels masks
+ if (!profileToImport->isValid()) {
+ continue;
+ }
+ if (std::find_if(mProfiles.begin(), mProfiles.end(),
+ [profileToImport](const auto &profile) {
+ return *profile == *profileToImport; }) == mProfiles.end()) {
+ addAudioProfile(profileToImport);
+ }
+ }
+}
+
+void AudioPort::toAudioPort(struct audio_port *port) const {
// TODO: update this function once audio_port structure reflects the new profile definition.
// For compatibility reason: flatening the AudioProfile into audio_port structure.
FormatSet flatenedFormats;
@@ -64,7 +80,7 @@
}
}
-void AudioPortBase::dump(std::string *dst, int spaces, bool verbose) const {
+void AudioPort::dump(std::string *dst, int spaces, bool verbose) const {
if (!mName.empty()) {
dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str()));
}
@@ -84,4 +100,92 @@
}
}
+void AudioPort::log(const char* indent) const
+{
+ ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
+}
+
+// --- AudioPortConfig class implementation
+
+status_t AudioPortConfig::applyAudioPortConfig(
+ const struct audio_port_config *config,
+ struct audio_port_config *backupConfig __unused)
+{
+ if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+ mSamplingRate = config->sample_rate;
+ }
+ if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+ mChannelMask = config->channel_mask;
+ }
+ if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+ mFormat = config->format;
+ }
+ if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
+ mGain = config->gain;
+ }
+
+ return NO_ERROR;
+}
+
+namespace {
+
+template<typename T>
+void updateField(
+ const T& portConfigField, T audio_port_config::*port_config_field,
+ struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig,
+ unsigned int configMask, T defaultValue)
+{
+ if (dstConfig->config_mask & configMask) {
+ if ((srcConfig != nullptr) && (srcConfig->config_mask & configMask)) {
+ dstConfig->*port_config_field = srcConfig->*port_config_field;
+ } else {
+ dstConfig->*port_config_field = portConfigField;
+ }
+ } else {
+ dstConfig->*port_config_field = defaultValue;
+ }
+}
+
+} // namespace
+
+void AudioPortConfig::toAudioPortConfig(
+ struct audio_port_config *dstConfig,
+ const struct audio_port_config *srcConfig) const
+{
+ updateField(mSamplingRate, &audio_port_config::sample_rate,
+ dstConfig, srcConfig, AUDIO_PORT_CONFIG_SAMPLE_RATE, 0u);
+ updateField(mChannelMask, &audio_port_config::channel_mask,
+ dstConfig, srcConfig, AUDIO_PORT_CONFIG_CHANNEL_MASK,
+ (audio_channel_mask_t)AUDIO_CHANNEL_NONE);
+ updateField(mFormat, &audio_port_config::format,
+ dstConfig, srcConfig, AUDIO_PORT_CONFIG_FORMAT, AUDIO_FORMAT_INVALID);
+ dstConfig->id = mId;
+
+ sp<AudioPort> audioport = getAudioPort();
+ if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) {
+ dstConfig->gain = mGain;
+ if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
+ && audioport->checkGain(&srcConfig->gain, srcConfig->gain.index) == OK) {
+ dstConfig->gain = srcConfig->gain;
+ }
+ } else {
+ dstConfig->gain.index = -1;
+ }
+ if (dstConfig->gain.index != -1) {
+ dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
+ } else {
+ dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
+ }
+}
+
+bool AudioPortConfig::hasGainController(bool canUseForVolume) const
+{
+ sp<AudioPort> audioport = getAudioPort();
+ if (!audioport) {
+ return false;
+ }
+ return canUseForVolume ? audioport->getGains().canUseForVolume()
+ : audioport->getGains().size() > 0;
+}
+
}
\ No newline at end of file
diff --git a/media/libaudiofoundation/include/media/AudioPortBase.h b/media/libaudiofoundation/include/media/AudioPortBase.h
index 869487d..b8d54de 100644
--- a/media/libaudiofoundation/include/media/AudioPortBase.h
+++ b/media/libaudiofoundation/include/media/AudioPortBase.h
@@ -27,13 +27,13 @@
namespace android {
-class AudioPortBase : public virtual RefBase
+class AudioPort : public virtual RefBase
{
public:
- AudioPortBase(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
+ AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
mName(name), mType(type), mRole(role) {}
- virtual ~AudioPortBase() = default;
+ virtual ~AudioPort() = default;
void setName(const std::string &name) { mName = name; }
const std::string &getName() const { return mName; }
@@ -41,8 +41,6 @@
audio_port_type_t getType() const { return mType; }
audio_port_role_t getRole() const { return mRole; }
- virtual const std::string getTagName() const = 0;
-
void setGains(const AudioGains &gains) { mGains = gains; }
const AudioGains &getGains() const { return mGains; }
@@ -57,9 +55,13 @@
bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
+ bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
+
void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
AudioProfileVector &getAudioProfiles() { return mProfiles; }
+ virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
+
status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
if (index < 0 || (size_t)index >= mGains.size()) {
return BAD_VALUE;
@@ -75,6 +77,8 @@
void dump(std::string *dst, int spaces, bool verbose = true) const;
+ void log(const char* indent) const;
+
AudioGains mGains; // gain controllers
protected:
std::string mName;
@@ -84,24 +88,31 @@
};
-class AudioPortConfigBase : public virtual RefBase
+class AudioPortConfig : public virtual RefBase
{
public:
- virtual ~AudioPortConfigBase() = default;
+ virtual ~AudioPortConfig() = default;
+
+ virtual sp<AudioPort> getAudioPort() const = 0;
virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
- struct audio_port_config *backupConfig = NULL) = 0;
+ struct audio_port_config *backupConfig = NULL);
+
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
- const struct audio_port_config *srcConfig = NULL) const = 0;
+ const struct audio_port_config *srcConfig = NULL) const;
unsigned int getSamplingRate() const { return mSamplingRate; }
audio_format_t getFormat() const { return mFormat; }
audio_channel_mask_t getChannelMask() const { return mChannelMask; }
+ audio_port_handle_t getId() const { return mId; }
+
+ bool hasGainController(bool canUseForVolume = false) const;
protected:
unsigned int mSamplingRate = 0u;
audio_format_t mFormat = AUDIO_FORMAT_INVALID;
audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE;
+ audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
struct audio_gain_config mGain = { .index = -1 };
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
index 646ef31..b692592 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
@@ -25,20 +25,15 @@
namespace android {
-class AudioPort;
+class PolicyAudioPort;
class AudioRoute;
-class AudioPortVector : public Vector<sp<AudioPort> >
-{
-public:
- sp<AudioPort> findByTagName(const std::string &tagName) const;
-};
+using PolicyAudioPortVector = Vector<sp<PolicyAudioPort>>;
+using AudioRouteVector = Vector<sp<AudioRoute>>;
+sp<PolicyAudioPort> findByTagName(const PolicyAudioPortVector& policyAudioPortVector,
+ const std::string &tagName);
-class AudioRouteVector : public Vector<sp<AudioRoute> >
-{
-public:
- void dump(String8 *dst, int spaces) const;
-};
+void dumpAudioRouteVector(const AudioRouteVector& audioRouteVector, String8 *dst, int spaces);
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 37f9d14..df31ab7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -34,13 +34,17 @@
// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
// and keep track of the usage of this input.
-class AudioInputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
- , public ClientMapHandler<RecordClientDescriptor>
+class AudioInputDescriptor: public AudioPortConfig,
+ public PolicyAudioPortConfig,
+ public AudioIODescriptorInterface,
+ public ClientMapHandler<RecordClientDescriptor>
{
public:
- explicit AudioInputDescriptor(const sp<IOProfile>& profile,
- AudioPolicyClientInterface *clientInterface);
- audio_port_handle_t getId() const;
+ AudioInputDescriptor(const sp<IOProfile>& profile,
+ AudioPolicyClientInterface *clientInterface);
+
+ virtual ~AudioInputDescriptor() = default;
+
audio_module_handle_t getModuleHandle() const;
audio_devices_t getDeviceType() const { return (mDevice != nullptr) ?
@@ -56,9 +60,18 @@
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
const sp<IOProfile> mProfile; // I/O profile this output derives from
+ // PolicyAudioPortConfig
+ virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
+ return mProfile;
+ }
+
+ // AudioPortConfig
+ virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
+ struct audio_port_config *backupConfig = NULL);
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
virtual sp<AudioPort> getAudioPort() const { return mProfile; }
+
void toAudioPort(struct audio_port *port) const;
void setPreemptedSessions(const SortedVector<audio_session_t>& sessions);
SortedVector<audio_session_t> getPreemptedSessions() const;
@@ -111,7 +124,6 @@
void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);
audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
sp<DeviceDescriptor> mDevice = nullptr; /**< current device this input is routed to */
// Because a preemptible capture session can preempt another one, we end up in an endless loop
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index cd54085..051d268 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -138,18 +138,19 @@
// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
-class AudioOutputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
- , public ClientMapHandler<TrackClientDescriptor>
+class AudioOutputDescriptor: public AudioPortConfig,
+ public PolicyAudioPortConfig,
+ public AudioIODescriptorInterface,
+ public ClientMapHandler<TrackClientDescriptor>
{
public:
- AudioOutputDescriptor(const sp<AudioPort>& port,
+ AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
AudioPolicyClientInterface *clientInterface);
virtual ~AudioOutputDescriptor() {}
void dump(String8 *dst) const override;
void log(const char* indent);
- audio_port_handle_t getId() const;
virtual DeviceVector devices() const { return mDevices; }
bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
virtual DeviceVector supportedDevices() const { return mDevices; }
@@ -245,9 +246,19 @@
mRoutingActivities[ps].setMutedByDevice(isMuted);
}
+ // PolicyAudioPortConfig
+ virtual sp<PolicyAudioPort> getPolicyAudioPort() const
+ {
+ return mPolicyAudioPort;
+ }
+
+ // AudioPortConfig
+ virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
+ struct audio_port_config *backupConfig = NULL);
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
- virtual sp<AudioPort> getAudioPort() const { return mPort; }
+ virtual sp<AudioPort> getAudioPort() const { return mPolicyAudioPort->asAudioPort(); }
+
virtual void toAudioPort(struct audio_port *port) const;
audio_module_handle_t getModuleHandle() const;
@@ -289,11 +300,10 @@
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
protected:
- const sp<AudioPort> mPort;
+ const sp<PolicyAudioPort> mPolicyAudioPort;
AudioPolicyClientInterface * const mClientInterface;
uint32_t mGlobalActiveCount = 0; // non-client-specific active count
audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
// The ActiveClients shows the clients that contribute to the @VolumeSource counts
// and may include upstream clients from a duplicating thread.
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 3a09391..5824b28 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -33,24 +33,24 @@
class HwModule;
class AudioRoute;
-class AudioPort : public AudioPortBase, private HandleGenerator<audio_port_handle_t>
+class PolicyAudioPort : public virtual RefBase, private HandleGenerator<audio_port_handle_t>
{
public:
- AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
- AudioPortBase(name, type, role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
+ PolicyAudioPort() : mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
- virtual ~AudioPort() {}
+ virtual ~PolicyAudioPort() = default;
- void addAudioProfile(const sp<AudioProfile> &profile) {
- addAudioProfileAndSort(mProfiles, profile);
- }
+ virtual const std::string getTagName() const = 0;
+
+ virtual sp<AudioPort> asAudioPort() const = 0;
virtual void setFlags(uint32_t flags)
{
//force direct flag if offload flag is set: offloading implies a direct output stream
// and all common behaviors are driven by checking only the direct flag
// this should normally be set appropriately in the policy configuration file
- if (mRole == AUDIO_PORT_ROLE_SOURCE && (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
+ if (asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE &&
+ (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
flags |= AUDIO_OUTPUT_FLAG_DIRECT;
}
mFlags = flags;
@@ -64,10 +64,6 @@
// Audio port IDs are in a different namespace than AudioFlinger unique IDs
static audio_port_handle_t getNextUniqueId();
- virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
-
- bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
-
// searches for an exact match
virtual status_t checkExactAudioProfile(const struct audio_port_config *config) const;
@@ -78,7 +74,8 @@
audio_format_t &format) const
{
return checkCompatibleProfile(
- mProfiles, samplingRate, channelMask, format, mType, mRole);
+ asAudioPort()->getAudioProfiles(), samplingRate, channelMask, format,
+ asAudioPort()->getType(), asAudioPort()->getRole());
}
void pickAudioProfile(uint32_t &samplingRate,
@@ -105,15 +102,14 @@
inline bool isDirectOutput() const
{
- return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
+ return (asAudioPort()->getType() == AUDIO_PORT_TYPE_MIX) &&
+ (asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE) &&
(mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
}
void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
const AudioRouteVector &getRoutes() const { return mRoutes; }
- void log(const char* indent) const;
-
private:
void pickChannelMask(audio_channel_mask_t &channelMask,
const ChannelMaskSet &channelMasks) const;
@@ -124,23 +120,32 @@
AudioRouteVector mRoutes; // Routes involving this port
};
-class AudioPortConfig : public AudioPortConfigBase
+class PolicyAudioPortConfig : public virtual RefBase
{
public:
- status_t applyAudioPortConfig(const struct audio_port_config *config,
- struct audio_port_config *backupConfig = NULL) override;
+ virtual ~PolicyAudioPortConfig() = default;
- virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
- const struct audio_port_config *srcConfig = NULL) const override;
+ virtual sp<PolicyAudioPort> getPolicyAudioPort() const = 0;
- virtual sp<AudioPort> getAudioPort() const = 0;
+ status_t validationBeforeApplyConfig(const struct audio_port_config *config) const;
- virtual bool hasSameHwModuleAs(const sp<AudioPortConfig>& other) const {
- return (other != 0) && (other->getAudioPort() != 0) && (getAudioPort() != 0) &&
- (other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle());
+ void applyPolicyAudioPortConfig(const struct audio_port_config *config) {
+ if (config->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
+ mFlags = config->flags;
+ }
}
- bool hasGainController(bool canUseForVolume = false) const;
+ void toPolicyAudioPortConfig(
+ struct audio_port_config *dstConfig,
+ const struct audio_port_config *srcConfig = NULL) const;
+
+
+ virtual bool hasSameHwModuleAs(const sp<PolicyAudioPortConfig>& other) const {
+ return (other.get() != nullptr) && (other->getPolicyAudioPort().get() != nullptr) &&
+ (getPolicyAudioPort().get() != nullptr) &&
+ (other->getPolicyAudioPort()->getModuleHandle() ==
+ getPolicyAudioPort()->getModuleHandle());
+ }
union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE };
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
index 0357ff4..a7def3e 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
@@ -25,7 +25,7 @@
namespace android
{
-class AudioPort;
+class PolicyAudioPort;
class DeviceDescriptor;
typedef enum {
@@ -38,11 +38,11 @@
public:
explicit AudioRoute(audio_route_type_t type) : mType(type) {}
- void setSources(const AudioPortVector &sources) { mSources = sources; }
- const AudioPortVector &getSources() const { return mSources; }
+ void setSources(const PolicyAudioPortVector &sources) { mSources = sources; }
+ const PolicyAudioPortVector &getSources() const { return mSources; }
- void setSink(const sp<AudioPort> &sink) { mSink = sink; }
- const sp<AudioPort> &getSink() const { return mSink; }
+ void setSink(const sp<PolicyAudioPort> &sink) { mSink = sink; }
+ const sp<PolicyAudioPort> &getSink() const { return mSink; }
audio_route_type_t getType() const { return mType; }
@@ -57,13 +57,14 @@
* @return true if the audio route supports the connection between the sink and the source,
* false otherwise
*/
- bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+ bool supportsPatch(const sp<PolicyAudioPort> &srcPort,
+ const sp<PolicyAudioPort> &dstPort) const;
void dump(String8 *dst, int spaces) const;
private:
- AudioPortVector mSources;
- sp<AudioPort> mSink;
+ PolicyAudioPortVector mSources;
+ sp<PolicyAudioPort> mSink;
audio_route_type_t mType;
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index c2f1d93..364f63b 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -26,7 +26,8 @@
namespace android {
-class DeviceDescriptor : public AudioPort, public AudioPortConfig
+class DeviceDescriptor : public AudioPort, public AudioPortConfig,
+ public PolicyAudioPort, public PolicyAudioPortConfig
{
public:
// Note that empty name refers by convention to a generic device.
@@ -36,6 +37,10 @@
virtual ~DeviceDescriptor() {}
+ virtual void addAudioProfile(const sp<AudioProfile> &profile) {
+ addAudioProfileAndSort(mProfiles, profile);
+ }
+
virtual const std::string getTagName() const { return mTagName; }
audio_devices_t type() const { return mDeviceType; }
@@ -56,19 +61,33 @@
bool supportsFormat(audio_format_t format);
+ // PolicyAudioPortConfig
+ virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
+ return static_cast<PolicyAudioPort*>(const_cast<DeviceDescriptor*>(this));
+ }
+
// AudioPortConfig
- virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
+ virtual sp<AudioPort> getAudioPort() const {
+ return static_cast<AudioPort*>(const_cast<DeviceDescriptor*>(this));
+ }
+ virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
+ struct audio_port_config *backupConfig = NULL);
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
- // AudioPort
+ // PolicyAudioPort
+ virtual sp<AudioPort> asAudioPort() const {
+ return static_cast<AudioPort*>(const_cast<DeviceDescriptor*>(this));
+ }
virtual void attach(const sp<HwModule>& module);
virtual void detach();
+ // AudioPort
virtual void toAudioPort(struct audio_port *port) const;
- virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
- audio_port_handle_t getId() const;
+ void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
+ bool force = false);
+
void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
void log() const;
std::string toString() const;
@@ -78,7 +97,6 @@
std::string mTagName; // Unique human readable identifier for a device port found in conf file.
audio_devices_t mDeviceType;
FormatVector mEncodedFormats;
- audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
audio_format_t mCurrentEncodedFormat;
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 65c886a..028cb63 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -92,9 +92,9 @@
audio_module_handle_t getHandle() const { return mHandle; }
void setHandle(audio_module_handle_t handle);
- sp<AudioPort> findPortByTagName(const std::string &tagName) const
+ sp<PolicyAudioPort> findPortByTagName(const std::string &tagName) const
{
- return mPorts.findByTagName(tagName);
+ return findByTagName(mPorts, tagName);
}
/**
@@ -106,7 +106,8 @@
* @return true if the HwModule supports the connection between the sink and the source,
* false otherwise
*/
- bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+ bool supportsPatch(const sp<PolicyAudioPort> &srcPort,
+ const sp<PolicyAudioPort> &dstPort) const;
// TODO remove from here (split serialization)
void dump(String8 *dst) const;
@@ -122,7 +123,7 @@
DeviceVector mDeclaredDevices; // devices declared in audio_policy configuration file.
DeviceVector mDynamicDevices; /**< devices that can be added/removed at runtime (e.g. rsbumix)*/
AudioRouteVector mRoutes;
- AudioPortVector mPorts;
+ PolicyAudioPortVector mPorts;
};
class HwModuleCollection : public Vector<sp<HwModule> >
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 419dd35..d1bc4c7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -31,7 +31,7 @@
// It is used by the policy manager to determine if an output or input is suitable for
// a given use case, open/close it accordingly and connect/disconnect audio tracks
// to/from it.
-class IOProfile : public AudioPort
+class IOProfile : public AudioPort, public PolicyAudioPort
{
public:
IOProfile(const std::string &name, audio_port_role_t role)
@@ -41,9 +41,19 @@
maxActiveCount(1),
curActiveCount(0) {}
+ virtual ~IOProfile() = default;
+
// For a Profile aka MixPort, tag name and name are equivalent.
virtual const std::string getTagName() const { return getName(); }
+ virtual void addAudioProfile(const sp<AudioProfile> &profile) {
+ addAudioProfileAndSort(mProfiles, profile);
+ }
+
+ virtual sp<AudioPort> asAudioPort() const {
+ return static_cast<AudioPort*>(const_cast<IOProfile*>(this));
+ }
+
// FIXME: this is needed because shared MMAP stream clients use the same audio session.
// Once capture clients are tracked individually and not per session this can be removed
// MMAP no IRQ input streams do not have the default limitation of one active client
@@ -52,7 +62,7 @@
// flags are parsed before maxActiveCount by the serializer.
void setFlags(uint32_t flags) override
{
- AudioPort::setFlags(flags);
+ PolicyAudioPort::setFlags(flags);
if (getRole() == AUDIO_PORT_ROLE_SINK && (flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
maxActiveCount = 0;
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
index b391a09..4968699 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
@@ -24,9 +24,10 @@
namespace android {
-sp<AudioPort> AudioPortVector::findByTagName(const std::string &tagName) const
+sp<PolicyAudioPort> findByTagName(const PolicyAudioPortVector& policyAudioPortVector,
+ const std::string &tagName)
{
- for (const auto& port : *this) {
+ for (const auto& port : policyAudioPortVector) {
if (port->getTagName() == tagName) {
return port;
}
@@ -34,15 +35,15 @@
return nullptr;
}
-void AudioRouteVector::dump(String8 *dst, int spaces) const
+void dumpAudioRouteVector(const AudioRouteVector& audioRouteVector, String8 *dst, int spaces)
{
- if (isEmpty()) {
+ if (audioRouteVector.isEmpty()) {
return;
}
- dst->appendFormat("\n%*sAudio Routes (%zu):\n", spaces, "", size());
- for (size_t i = 0; i < size(); i++) {
+ dst->appendFormat("\n%*sAudio Routes (%zu):\n", spaces, "", audioRouteVector.size());
+ for (size_t i = 0; i < audioRouteVector.size(); i++) {
dst->appendFormat("%*s- Route %zu:\n", spaces, "", i + 1);
- itemAt(i)->dump(dst, 4);
+ audioRouteVector.itemAt(i)->dump(dst, 4);
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 7cb2e10..f7cb4dd 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -48,16 +48,29 @@
return mProfile->getModuleHandle();
}
-audio_port_handle_t AudioInputDescriptor::getId() const
-{
- return mId;
-}
-
audio_source_t AudioInputDescriptor::source() const
{
return getHighestPriorityAttributes().source;
}
+status_t AudioInputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
+ audio_port_config *backupConfig)
+{
+ struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
+ status_t status = NO_ERROR;
+
+ toAudioPortConfig(&localBackupConfig);
+ if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
+ AudioPortConfig::applyAudioPortConfig(config, backupConfig);
+ applyPolicyAudioPortConfig(config);
+ }
+
+ if (backupConfig != NULL) {
+ *backupConfig = localBackupConfig;
+ }
+ return status;
+}
+
void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
@@ -70,8 +83,8 @@
}
AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+ toPolicyAudioPortConfig(dstConfig, srcConfig);
- dstConfig->id = mId;
dstConfig->role = AUDIO_PORT_ROLE_SINK;
dstConfig->type = AUDIO_PORT_TYPE_MIX;
dstConfig->ext.mix.hw_module = getModuleHandle();
@@ -234,7 +247,7 @@
mSamplingRate = lConfig.sample_rate;
mChannelMask = lConfig.channel_mask;
mFormat = lConfig.format;
- mId = AudioPort::getNextUniqueId();
+ mId = PolicyAudioPort::getNextUniqueId();
mIoHandle = *input;
mProfile->curOpenCount++;
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 6f0c3f5..00000fe 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -34,14 +34,14 @@
namespace android {
-AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
+AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
AudioPolicyClientInterface *clientInterface)
- : mPort(port), mClientInterface(clientInterface)
+ : mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
{
- if (mPort.get() != nullptr) {
- mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
- if (mPort->getGains().size() > 0) {
- mPort->getGains()[0]->getDefaultConfig(&mGain);
+ if (mPolicyAudioPort.get() != nullptr) {
+ mPolicyAudioPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
+ if (mPolicyAudioPort->asAudioPort()->getGains().size() > 0) {
+ mPolicyAudioPort->asAudioPort()->getGains()[0]->getDefaultConfig(&mGain);
}
}
}
@@ -55,7 +55,8 @@
audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
{
- return mPort.get() != nullptr ? mPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
+ return mPolicyAudioPort.get() != nullptr ?
+ mPolicyAudioPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
}
audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
@@ -68,11 +69,6 @@
mPatchHandle = handle;
}
-audio_port_handle_t AudioOutputDescriptor::getId() const
-{
- return mId;
-}
-
bool AudioOutputDescriptor::sharesHwModuleWith(
const sp<AudioOutputDescriptor>& outputDesc)
{
@@ -167,9 +163,27 @@
return false;
}
-void AudioOutputDescriptor::toAudioPortConfig(
- struct audio_port_config *dstConfig,
- const struct audio_port_config *srcConfig) const
+status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
+ audio_port_config *backupConfig)
+{
+ struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
+ status_t status = NO_ERROR;
+
+ toAudioPortConfig(&localBackupConfig);
+ if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
+ AudioPortConfig::applyAudioPortConfig(config, backupConfig);
+ applyPolicyAudioPortConfig(config);
+ }
+
+ if (backupConfig != NULL) {
+ *backupConfig = localBackupConfig;
+ }
+ return status;
+}
+
+
+void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
+ const struct audio_port_config *srcConfig) const
{
dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
@@ -177,8 +191,8 @@
dstConfig->config_mask |= srcConfig->config_mask;
}
AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+ toPolicyAudioPortConfig(dstConfig, srcConfig);
- dstConfig->id = mId;
dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
dstConfig->type = AUDIO_PORT_TYPE_MIX;
dstConfig->ext.mix.hw_module = getModuleHandle();
@@ -188,7 +202,7 @@
void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const
{
// Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
- mPort->toAudioPort(port);
+ mPolicyAudioPort->asAudioPort()->toAudioPort(port);
port->id = mId;
port->ext.mix.hw_module = getModuleHandle();
}
@@ -503,7 +517,7 @@
mSamplingRate = lConfig.sample_rate;
mChannelMask = lConfig.channel_mask;
mFormat = lConfig.format;
- mId = AudioPort::getNextUniqueId();
+ mId = PolicyAudioPort::getNextUniqueId();
mIoHandle = *output;
mProfile->curOpenCount++;
}
@@ -589,7 +603,7 @@
return INVALID_OPERATION;
}
- mId = AudioPort::getNextUniqueId();
+ mId = PolicyAudioPort::getNextUniqueId();
mIoHandle = *ioHandle;
mOutput1 = output1;
mOutput2 = output2;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index fd6c6dc..ffb03af 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -27,80 +27,61 @@
namespace android {
-// --- AudioPort class implementation
-void AudioPort::attach(const sp<HwModule>& module)
+// --- PolicyAudioPort class implementation
+void PolicyAudioPort::attach(const sp<HwModule>& module)
{
- ALOGV("%s: attaching module %s to port %s", __FUNCTION__, getModuleName(), mName.c_str());
+ ALOGV("%s: attaching module %s to port %s",
+ __FUNCTION__, getModuleName(), asAudioPort()->getName().c_str());
mModule = module;
}
-void AudioPort::detach()
+void PolicyAudioPort::detach()
{
mModule = nullptr;
}
// Note that is a different namespace than AudioFlinger unique IDs
-audio_port_handle_t AudioPort::getNextUniqueId()
+audio_port_handle_t PolicyAudioPort::getNextUniqueId()
{
return getNextHandle();
}
-audio_module_handle_t AudioPort::getModuleHandle() const
+audio_module_handle_t PolicyAudioPort::getModuleHandle() const
{
return mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
}
-uint32_t AudioPort::getModuleVersionMajor() const
+uint32_t PolicyAudioPort::getModuleVersionMajor() const
{
return mModule != 0 ? mModule->getHalVersionMajor() : 0;
}
-const char *AudioPort::getModuleName() const
+const char *PolicyAudioPort::getModuleName() const
{
return mModule != 0 ? mModule->getName() : "invalid module";
}
-void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
-{
- for (const auto& profileToImport : port->mProfiles) {
- if (profileToImport->isValid()) {
- // Import only valid port, i.e. valid format, non empty rates and channels masks
- bool hasSameProfile = false;
- for (const auto& profile : mProfiles) {
- if (*profile == *profileToImport) {
- // never import a profile twice
- hasSameProfile = true;
- break;
- }
- }
- if (hasSameProfile) { // never import a same profile twice
- continue;
- }
- addAudioProfile(profileToImport);
- }
- }
-}
-
-status_t AudioPort::checkExactAudioProfile(const struct audio_port_config *config) const
+status_t PolicyAudioPort::checkExactAudioProfile(const struct audio_port_config *config) const
{
status_t status = NO_ERROR;
auto config_mask = config->config_mask;
if (config_mask & AUDIO_PORT_CONFIG_GAIN) {
config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
- status = checkGain(&config->gain, config->gain.index);
+ status = asAudioPort()->checkGain(&config->gain, config->gain.index);
if (status != NO_ERROR) {
return status;
}
}
if (config_mask != 0) {
// TODO should we check sample_rate / channel_mask / format separately?
- status = checkExactProfile(mProfiles, config->sample_rate,
+ status = checkExactProfile(asAudioPort()->getAudioProfiles(), config->sample_rate,
config->channel_mask, config->format);
}
return status;
}
-void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateSet &samplingRates) const
+void PolicyAudioPort::pickSamplingRate(uint32_t &pickedRate,
+ const SampleRateSet &samplingRates) const
{
pickedRate = 0;
// For direct outputs, pick minimum sampling rate: this helps ensuring that the
@@ -120,7 +101,7 @@
// For mixed output and inputs, use max mixer sampling rates. Do not
// limit sampling rate otherwise
// For inputs, also see checkCompatibleSamplingRate().
- if (mType != AUDIO_PORT_TYPE_MIX) {
+ if (asAudioPort()->getType() == AUDIO_PORT_TYPE_MIX) {
maxRate = UINT_MAX;
}
// TODO: should mSamplingRates[] be ordered in terms of our preference
@@ -134,8 +115,8 @@
}
}
-void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
- const ChannelMaskSet &channelMasks) const
+void PolicyAudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
+ const ChannelMaskSet &channelMasks) const
{
pickedChannelMask = AUDIO_CHANNEL_NONE;
// For direct outputs, pick minimum channel count: this helps ensuring that the
@@ -145,7 +126,7 @@
uint32_t channelCount = UINT_MAX;
for (const auto channelMask : channelMasks) {
uint32_t cnlCount;
- if (useInputChannelMask()) {
+ if (asAudioPort()->useInputChannelMask()) {
cnlCount = audio_channel_count_from_in_mask(channelMask);
} else {
cnlCount = audio_channel_count_from_out_mask(channelMask);
@@ -161,12 +142,12 @@
// For mixed output and inputs, use max mixer channel count. Do not
// limit channel count otherwise
- if (mType != AUDIO_PORT_TYPE_MIX) {
+ if (asAudioPort()->getType() != AUDIO_PORT_TYPE_MIX) {
maxCount = UINT_MAX;
}
for (const auto channelMask : channelMasks) {
uint32_t cnlCount;
- if (useInputChannelMask()) {
+ if (asAudioPort()->useInputChannelMask()) {
cnlCount = audio_channel_count_from_in_mask(channelMask);
} else {
cnlCount = audio_channel_count_from_out_mask(channelMask);
@@ -180,7 +161,7 @@
}
/* format in order of increasing preference */
-const audio_format_t AudioPort::sPcmFormatCompareTable[] = {
+const audio_format_t PolicyAudioPort::sPcmFormatCompareTable[] = {
AUDIO_FORMAT_DEFAULT,
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_FORMAT_PCM_8_24_BIT,
@@ -189,7 +170,7 @@
AUDIO_FORMAT_PCM_FLOAT,
};
-int AudioPort::compareFormats(audio_format_t format1, audio_format_t format2)
+int PolicyAudioPort::compareFormats(audio_format_t format1, audio_format_t format2)
{
// NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any
// compressed format and better than any PCM format. This is by design of pickFormat()
@@ -219,7 +200,7 @@
return index1 - index2;
}
-uint32_t AudioPort::formatDistance(audio_format_t format1, audio_format_t format2)
+uint32_t PolicyAudioPort::formatDistance(audio_format_t format1, audio_format_t format2)
{
if (format1 == format2) {
return 0;
@@ -233,43 +214,44 @@
return abs(diffBytes);
}
-bool AudioPort::isBetterFormatMatch(audio_format_t newFormat,
- audio_format_t currentFormat,
- audio_format_t targetFormat)
+bool PolicyAudioPort::isBetterFormatMatch(audio_format_t newFormat,
+ audio_format_t currentFormat,
+ audio_format_t targetFormat)
{
return formatDistance(newFormat, targetFormat) < formatDistance(currentFormat, targetFormat);
}
-void AudioPort::pickAudioProfile(uint32_t &samplingRate,
- audio_channel_mask_t &channelMask,
- audio_format_t &format) const
+void PolicyAudioPort::pickAudioProfile(uint32_t &samplingRate,
+ audio_channel_mask_t &channelMask,
+ audio_format_t &format) const
{
format = AUDIO_FORMAT_DEFAULT;
samplingRate = 0;
channelMask = AUDIO_CHANNEL_NONE;
// special case for uninitialized dynamic profile
- if (!mProfiles.hasValidProfile()) {
+ if (!asAudioPort()->hasValidAudioProfile()) {
return;
}
audio_format_t bestFormat = sPcmFormatCompareTable[ARRAY_SIZE(sPcmFormatCompareTable) - 1];
// For mixed output and inputs, use best mixer output format.
// Do not limit format otherwise
- if ((mType != AUDIO_PORT_TYPE_MIX) || isDirectOutput()) {
+ if ((asAudioPort()->getType() != AUDIO_PORT_TYPE_MIX) || isDirectOutput()) {
bestFormat = AUDIO_FORMAT_INVALID;
}
- for (size_t i = 0; i < mProfiles.size(); i ++) {
- if (!mProfiles[i]->isValid()) {
+ const AudioProfileVector& audioProfiles = asAudioPort()->getAudioProfiles();
+ for (size_t i = 0; i < audioProfiles.size(); i ++) {
+ if (!audioProfiles[i]->isValid()) {
continue;
}
- audio_format_t formatToCompare = mProfiles[i]->getFormat();
+ audio_format_t formatToCompare = audioProfiles[i]->getFormat();
if ((compareFormats(formatToCompare, format) > 0) &&
(compareFormats(formatToCompare, bestFormat) <= 0)) {
uint32_t pickedSamplingRate = 0;
audio_channel_mask_t pickedChannelMask = AUDIO_CHANNEL_NONE;
- pickChannelMask(pickedChannelMask, mProfiles[i]->getChannels());
- pickSamplingRate(pickedSamplingRate, mProfiles[i]->getSampleRates());
+ pickChannelMask(pickedChannelMask, audioProfiles[i]->getChannels());
+ pickSamplingRate(pickedSamplingRate, audioProfiles[i]->getSampleRates());
if (formatToCompare != AUDIO_FORMAT_DEFAULT && pickedChannelMask != AUDIO_CHANNEL_NONE
&& pickedSamplingRate != 0) {
@@ -280,120 +262,33 @@
}
}
}
- ALOGV("%s Port[nm:%s] profile rate=%d, format=%d, channels=%d", __FUNCTION__, mName.c_str(),
- samplingRate, channelMask, format);
+ ALOGV("%s Port[nm:%s] profile rate=%d, format=%d, channels=%d", __FUNCTION__,
+ asAudioPort()->getName().c_str(), samplingRate, channelMask, format);
}
-void AudioPort::log(const char* indent) const
+// --- PolicyAudioPortConfig class implementation
+
+status_t PolicyAudioPortConfig::validationBeforeApplyConfig(
+ const struct audio_port_config *config) const
{
- ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
+ sp<PolicyAudioPort> policyAudioPort = getPolicyAudioPort();
+ return policyAudioPort ? policyAudioPort->checkExactAudioProfile(config) : NO_INIT;
}
-// --- AudioPortConfig class implementation
-
-status_t AudioPortConfig::applyAudioPortConfig(const struct audio_port_config *config,
- struct audio_port_config *backupConfig)
+void PolicyAudioPortConfig::toPolicyAudioPortConfig(struct audio_port_config *dstConfig,
+ const struct audio_port_config *srcConfig) const
{
- struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
- status_t status = NO_ERROR;
-
- toAudioPortConfig(&localBackupConfig);
-
- sp<AudioPort> audioport = getAudioPort();
- if (audioport == 0) {
- status = NO_INIT;
- goto exit;
- }
- status = audioport->checkExactAudioProfile(config);
- if (status != NO_ERROR) {
- goto exit;
- }
- if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
- mSamplingRate = config->sample_rate;
- }
- if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
- mChannelMask = config->channel_mask;
- }
- if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
- mFormat = config->format;
- }
- if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
- mGain = config->gain;
- }
- if (config->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
- mFlags = config->flags;
- }
-
-exit:
- if (status != NO_ERROR) {
- applyAudioPortConfig(&localBackupConfig);
- }
- if (backupConfig != NULL) {
- *backupConfig = localBackupConfig;
- }
- return status;
-}
-
-namespace {
-
-template<typename T>
-void updateField(
- const T& portConfigField, T audio_port_config::*port_config_field,
- struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig,
- unsigned int configMask, T defaultValue)
-{
- if (dstConfig->config_mask & configMask) {
- if ((srcConfig != nullptr) && (srcConfig->config_mask & configMask)) {
- dstConfig->*port_config_field = srcConfig->*port_config_field;
+ if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
+ if ((srcConfig != nullptr) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FLAGS)) {
+ dstConfig->flags = srcConfig->flags;
} else {
- dstConfig->*port_config_field = portConfigField;
+ dstConfig->flags = mFlags;
}
} else {
- dstConfig->*port_config_field = defaultValue;
+ dstConfig->flags = { AUDIO_INPUT_FLAG_NONE };
}
}
-} // namespace
-void AudioPortConfig::toAudioPortConfig(struct audio_port_config *dstConfig,
- const struct audio_port_config *srcConfig) const
-{
- updateField(mSamplingRate, &audio_port_config::sample_rate,
- dstConfig, srcConfig, AUDIO_PORT_CONFIG_SAMPLE_RATE, 0u);
- updateField(mChannelMask, &audio_port_config::channel_mask,
- dstConfig, srcConfig, AUDIO_PORT_CONFIG_CHANNEL_MASK,
- (audio_channel_mask_t)AUDIO_CHANNEL_NONE);
- updateField(mFormat, &audio_port_config::format,
- dstConfig, srcConfig, AUDIO_PORT_CONFIG_FORMAT, AUDIO_FORMAT_INVALID);
-
- sp<AudioPort> audioport = getAudioPort();
- if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) {
- dstConfig->gain = mGain;
- if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
- && audioport->checkGain(&srcConfig->gain, srcConfig->gain.index) == OK) {
- dstConfig->gain = srcConfig->gain;
- }
- } else {
- dstConfig->gain.index = -1;
- }
- if (dstConfig->gain.index != -1) {
- dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
- } else {
- dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
- }
-
- updateField(mFlags, &audio_port_config::flags,
- dstConfig, srcConfig, AUDIO_PORT_CONFIG_FLAGS, { AUDIO_INPUT_FLAG_NONE });
-}
-
-bool AudioPortConfig::hasGainController(bool canUseForVolume) const
-{
- sp<AudioPort> audioport = getAudioPort();
- if (audioport == nullptr) {
- return false;
- }
- return canUseForVolume ? audioport->getGains().canUseForVolume()
- : audioport->getGains().size() > 0;
-}
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp
index 3d2916b..600889d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp
@@ -36,7 +36,7 @@
std::sort(audioProfileVector.begin(), audioProfileVector.end(),
[](const sp<AudioProfile> & a, const sp<AudioProfile> & b)
{
- return AudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
+ return PolicyAudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
});
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
index 0f35ff8..2a18f19 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
@@ -36,7 +36,8 @@
dst->append("\n");
}
-bool AudioRoute::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const
+bool AudioRoute::supportsPatch(const sp<PolicyAudioPort> &srcPort,
+ const sp<PolicyAudioPort> &dstPort) const
{
if (mSink == 0 || dstPort == 0 || dstPort != mSink) {
return false;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 018636d..51ac5f5 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -53,20 +53,15 @@
}
}
-audio_port_handle_t DeviceDescriptor::getId() const
-{
- return mId;
-}
-
void DeviceDescriptor::attach(const sp<HwModule>& module)
{
- AudioPort::attach(module);
+ PolicyAudioPort::attach(module);
mId = getNextUniqueId();
}
void DeviceDescriptor::detach() {
mId = AUDIO_PORT_HANDLE_NONE;
- AudioPort::detach();
+ PolicyAudioPort::detach();
}
template<typename T>
@@ -315,6 +310,24 @@
}
}
+status_t DeviceDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
+ audio_port_config *backupConfig)
+{
+ struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
+ status_t status = NO_ERROR;
+
+ toAudioPortConfig(&localBackupConfig);
+ if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
+ AudioPortConfig::applyAudioPortConfig(config, backupConfig);
+ applyPolicyAudioPortConfig(config);
+ }
+
+ if (backupConfig != NULL) {
+ *backupConfig = localBackupConfig;
+ }
+ return status;
+}
+
void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
@@ -334,8 +347,8 @@
}
AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+ toPolicyAudioPortConfig(dstConfig, srcConfig);
- dstConfig->id = mId;
dstConfig->role = audio_is_output_device(mDeviceType) ?
AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
@@ -360,12 +373,13 @@
(void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.string());
}
-void DeviceDescriptor::importAudioPort(const sp<AudioPort>& port, bool force) {
- if (!force && !port->hasDynamicAudioProfile()) {
+void DeviceDescriptor::importAudioPortAndPickAudioProfile(
+ const sp<PolicyAudioPort>& policyPort, bool force) {
+ if (!force && !policyPort->asAudioPort()->hasDynamicAudioProfile()) {
return;
}
- AudioPort::importAudioPort(port);
- port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
+ AudioPort::importAudioPort(policyPort->asAudioPort());
+ policyPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
}
void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index c232775..7e65b20 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -156,7 +156,7 @@
sp<DeviceDescriptor> HwModule::getRouteSinkDevice(const sp<AudioRoute> &route) const
{
sp<DeviceDescriptor> sinkDevice = 0;
- if (route->getSink()->getType() == AUDIO_PORT_TYPE_DEVICE) {
+ if (route->getSink()->asAudioPort()->getType() == AUDIO_PORT_TYPE_DEVICE) {
sinkDevice = mDeclaredDevices.getDeviceFromTagName(route->getSink()->getTagName());
}
return sinkDevice;
@@ -166,7 +166,7 @@
{
DeviceVector sourceDevices;
for (const auto& source : route->getSources()) {
- if (source->getType() == AUDIO_PORT_TYPE_DEVICE) {
+ if (source->asAudioPort()->getType() == AUDIO_PORT_TYPE_DEVICE) {
sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(source->getTagName()));
}
}
@@ -186,7 +186,7 @@
for (const auto& stream : mInputProfiles) {
DeviceVector sourceDevices;
for (const auto& route : stream->getRoutes()) {
- sp<AudioPort> sink = route->getSink();
+ sp<PolicyAudioPort> sink = route->getSink();
if (sink == 0 || stream != sink) {
ALOGE("%s: Invalid route attached to input stream", __FUNCTION__);
continue;
@@ -207,7 +207,7 @@
for (const auto& stream : mOutputProfiles) {
DeviceVector sinkDevices;
for (const auto& route : stream->getRoutes()) {
- sp<AudioPort> source = route->getSources().findByTagName(stream->getTagName());
+ sp<PolicyAudioPort> source = findByTagName(route->getSources(), stream->getTagName());
if (source == 0 || stream != source) {
ALOGE("%s: Invalid route attached to output stream", __FUNCTION__);
continue;
@@ -229,7 +229,8 @@
mHandle = handle;
}
-bool HwModule::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const {
+bool HwModule::supportsPatch(const sp<PolicyAudioPort> &srcPort,
+ const sp<PolicyAudioPort> &dstPort) const {
for (const auto &route : mRoutes) {
if (route->supportsPatch(srcPort, dstPort)) {
return true;
@@ -259,7 +260,7 @@
}
mDeclaredDevices.dump(dst, String8("Declared"), 2, true);
mDynamicDevices.dump(dst, String8("Dynamic"), 2, true);
- mRoutes.dump(dst, 2);
+ dumpAudioRouteVector(mRoutes, dst, 2);
}
sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
@@ -381,7 +382,7 @@
// @todo quid of audio profile? import the profile from device of the same type?
const auto &isoTypeDeviceForProfile =
profile->getSupportedDevices().getDevice(type, String8(), AUDIO_FORMAT_DEFAULT);
- device->importAudioPort(isoTypeDeviceForProfile, true /* force */);
+ device->importAudioPortAndPickAudioProfile(isoTypeDeviceForProfile, true /* force */);
ALOGV("%s: adding device %s to profile %s", __FUNCTION__,
device->toString().c_str(), profile->getTagName().c_str());
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 861d174..ef1ddf7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -561,7 +561,7 @@
return Status::fromStatusT(BAD_VALUE);
}
// Convert Sink name to port pointer
- sp<AudioPort> sink = ctx->findPortByTagName(sinkAttr);
+ sp<PolicyAudioPort> sink = ctx->findPortByTagName(sinkAttr);
if (sink == NULL) {
ALOGE("%s: no sink found with name=%s", __func__, sinkAttr.c_str());
return Status::fromStatusT(BAD_VALUE);
@@ -574,13 +574,13 @@
return Status::fromStatusT(BAD_VALUE);
}
// Tokenize and Convert Sources name to port pointer
- AudioPortVector sources;
+ PolicyAudioPortVector sources;
std::unique_ptr<char[]> sourcesLiteral{strndup(
sourcesAttr.c_str(), strlen(sourcesAttr.c_str()))};
char *devTag = strtok(sourcesLiteral.get(), ",");
while (devTag != NULL) {
if (strlen(devTag) != 0) {
- sp<AudioPort> source = ctx->findPortByTagName(devTag);
+ sp<PolicyAudioPort> source = ctx->findPortByTagName(devTag);
if (source == NULL) {
ALOGE("%s: no source found with name=%s", __func__, devTag);
return Status::fromStatusT(BAD_VALUE);
@@ -592,7 +592,7 @@
sink->addRoute(route);
for (size_t i = 0; i < sources.size(); i++) {
- sp<AudioPort> source = sources.itemAt(i);
+ sp<PolicyAudioPort> source = sources.itemAt(i);
source->addRoute(route);
}
route->setSources(sources);
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index b895c2f..a43c5d7 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -212,7 +212,7 @@
String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
((availPrimaryInputDevices.getDevice(
txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
- (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
+ (primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
availableOutputDevices = availPrimaryOutputDevices;
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index db8d5fa..8816f7f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1109,7 +1109,7 @@
.channel_mask = config->channel_mask,
.format = config->format,
};
- *portId = AudioPort::getNextUniqueId();
+ *portId = PolicyAudioPort::getNextUniqueId();
sp<TrackClientDescriptor> clientDesc =
new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
@@ -1563,8 +1563,8 @@
// format match
if (format != AUDIO_FORMAT_INVALID) {
currentMatchCriteria[6] =
- AudioPort::kFormatDistanceMax -
- AudioPort::formatDistance(format, outputDesc->getFormat());
+ PolicyAudioPort::kFormatDistanceMax -
+ PolicyAudioPort::formatDistance(format, outputDesc->getFormat());
}
// primary output match
@@ -2088,7 +2088,7 @@
isSoundTrigger = attributes.source == AUDIO_SOURCE_HOTWORD &&
mSoundTriggerSessions.indexOfKey(session) >= 0;
- *portId = AudioPort::getNextUniqueId();
+ *portId = PolicyAudioPort::getNextUniqueId();
clientDesc = new RecordClientDescriptor(*portId, riid, uid, session, attributes, *config,
requestedDeviceId, attributes.source, flags,
@@ -2431,7 +2431,8 @@
const sp<AudioInputDescriptor> input = mInputs.valueAt(i);
if (input->clientsList().size() == 0
|| !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())
- || (input->getAudioPort()->getFlags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
+ || (input->getPolicyAudioPort()->getFlags()
+ & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
inputsToClose.push_back(mInputs.keyAt(i));
} else {
bool close = false;
@@ -3857,7 +3858,7 @@
return BAD_VALUE;
}
- *portId = AudioPort::getNextUniqueId();
+ *portId = PolicyAudioPort::getNextUniqueId();
struct audio_patch dummyPatch = {};
sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
@@ -4471,7 +4472,7 @@
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
- device->importAudioPort(inProfile, true);
+ device->importAudioPortAndPickAudioProfile(inProfile, true);
}
}
inputDesc->close();
@@ -4627,7 +4628,7 @@
// matching profile: save the sample rates, format and channel masks supported
// by the profile in our device descriptor
if (audio_device_is_digital(deviceType)) {
- device->importAudioPort(profile);
+ device->importAudioPortAndPickAudioProfile(profile);
}
break;
}
@@ -4729,7 +4730,7 @@
outputs.add(output);
// Load digital format info only for digital devices
if (audio_device_is_digital(deviceType)) {
- device->importAudioPort(profile);
+ device->importAudioPortAndPickAudioProfile(profile);
}
if (device_distinguishes_on_address(deviceType)) {
@@ -4823,7 +4824,7 @@
desc = mInputs.valueAt(input_index);
if (desc->mProfile == profile) {
if (audio_device_is_digital(device->type())) {
- device->importAudioPort(profile);
+ device->importAudioPortAndPickAudioProfile(profile);
}
break;
}
@@ -4872,7 +4873,7 @@
profile_index--;
} else {
if (audio_device_is_digital(device->type())) {
- device->importAudioPort(profile);
+ device->importAudioPortAndPickAudioProfile(profile);
}
ALOGV("checkInputsForDevice(): adding input %d", input);
}