1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <string> 20 #include <type_traits> 21 22 #include <android/media/AudioPort.h> 23 #include <android/media/AudioPortConfig.h> 24 #include <android/media/audio/common/ExtraAudioDescriptor.h> 25 #include <binder/Parcel.h> 26 #include <binder/Parcelable.h> 27 #include <media/AudioGain.h> 28 #include <media/AudioProfile.h> 29 #include <utils/Errors.h> 30 #include <utils/RefBase.h> 31 #include <system/audio.h> 32 #include <cutils/config_utils.h> 33 34 namespace android { 35 36 class AudioPort : public virtual RefBase 37 { 38 public: AudioPort(const std::string & name,audio_port_type_t type,audio_port_role_t role)39 AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) : 40 mName(name), mType(type), mRole(role) {} 41 42 virtual ~AudioPort() = default; 43 setName(const std::string & name)44 void setName(const std::string &name) { mName = name; } getName()45 const std::string &getName() const { return mName; } 46 getType()47 audio_port_type_t getType() const { return mType; } getRole()48 audio_port_role_t getRole() const { return mRole; } 49 50 virtual void setFlags(uint32_t flags); getFlags()51 uint32_t getFlags() const { return useInputChannelMask() ? mFlags.input : mFlags.output; } 52 setGains(const AudioGains & gains)53 void setGains(const AudioGains &gains) { mGains = gains; } getGains()54 const AudioGains &getGains() const { return mGains; } 55 56 virtual void toAudioPort(struct audio_port *port) const; 57 58 virtual void toAudioPort(struct audio_port_v7 *port) const; 59 addAudioProfile(const sp<AudioProfile> & profile)60 virtual void addAudioProfile(const sp<AudioProfile> &profile) { 61 mProfiles.add(profile); 62 } clearAudioProfiles()63 virtual void clearAudioProfiles() { 64 mProfiles.clearProfiles(); 65 } 66 hasValidAudioProfile()67 bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); } 68 hasDynamicAudioProfile()69 bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); } 70 setAudioProfiles(const AudioProfileVector & profiles)71 void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; } getAudioProfiles()72 AudioProfileVector &getAudioProfiles() { return mProfiles; } 73 setExtraAudioDescriptors(const std::vector<media::audio::common::ExtraAudioDescriptor> extraAudioDescriptors)74 void setExtraAudioDescriptors( 75 const std::vector<media::audio::common::ExtraAudioDescriptor> extraAudioDescriptors) { 76 mExtraAudioDescriptors = extraAudioDescriptors; 77 } getExtraAudioDescriptors()78 std::vector<media::audio::common::ExtraAudioDescriptor> &getExtraAudioDescriptors() { 79 return mExtraAudioDescriptors; 80 } 81 82 virtual void importAudioPort(const sp<AudioPort>& port, bool force = false); 83 84 virtual void importAudioPort(const audio_port_v7& port); 85 checkGain(const struct audio_gain_config * gainConfig,int index)86 status_t checkGain(const struct audio_gain_config *gainConfig, int index) const { 87 if (index < 0 || (size_t)index >= mGains.size()) { 88 return BAD_VALUE; 89 } 90 return mGains[index]->checkConfig(gainConfig); 91 } 92 useInputChannelMask()93 bool useInputChannelMask() const 94 { 95 return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) || 96 ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK)); 97 } 98 isDirectOutput()99 bool isDirectOutput() const 100 { 101 return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 102 ((mFlags.output & AUDIO_OUTPUT_FLAG_DIRECT) != 0); 103 } 104 isMmap()105 bool isMmap() const 106 { 107 return (mType == AUDIO_PORT_TYPE_MIX) 108 && (((mRole == AUDIO_PORT_ROLE_SOURCE) && 109 ((mFlags.output & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) != 0)) 110 || ((mRole == AUDIO_PORT_ROLE_SINK) && 111 ((mFlags.input & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0))); 112 } 113 114 void dump(std::string *dst, int spaces, 115 const char* extraInfo = nullptr, bool verbose = true) const; 116 117 void log(const char* indent) const; 118 119 bool equals(const sp<AudioPort>& other) const; 120 121 status_t writeToParcelable(media::AudioPort* parcelable) const; 122 status_t readFromParcelable(const media::AudioPort& parcelable); 123 124 AudioGains mGains; // gain controllers 125 // Maximum number of input or output streams that can be simultaneously 126 // opened for this profile. By convention 0 means no limit. To respect 127 // legacy behavior, initialized to 1 for output profiles and 0 for input 128 // profiles 129 // FIXME: IOProfile code used the same value for both cases. 130 uint32_t maxOpenCount = 1; 131 // Maximum number of input or output streams that can be simultaneously 132 // active for this profile. By convention 0 means no limit. To respect 133 // legacy behavior, initialized to 0 for output profiles and 1 for input 134 // profiles 135 // FIXME: IOProfile code used the same value for both cases. 136 uint32_t maxActiveCount = 1; 137 // Mute duration while changing device on this output profile. 138 uint32_t recommendedMuteDurationMs = 0; 139 140 protected: 141 std::string mName; 142 audio_port_type_t mType; 143 audio_port_role_t mRole; 144 AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels) 145 146 // Audio capabilities that are defined by hardware descriptors when the format is unrecognized 147 // by the platform, e.g. short audio descriptor in EDID for HDMI. 148 std::vector<media::audio::common::ExtraAudioDescriptor> mExtraAudioDescriptors; 149 union audio_io_flags mFlags = { .output = AUDIO_OUTPUT_FLAG_NONE }; 150 private: 151 template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value 152 || std::is_same<T, struct audio_port_v7>::value, int> = 0> toAudioPortBase(T * port)153 void toAudioPortBase(T* port) const { 154 port->role = mRole; 155 port->type = mType; 156 strlcpy(port->name, mName.c_str(), AUDIO_PORT_MAX_NAME_LEN); 157 port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS); 158 for (size_t i = 0; i < port->num_gains; i++) { 159 port->gains[i] = mGains[i]->getGain(); 160 } 161 } 162 }; 163 164 165 class AudioPortConfig : public virtual RefBase 166 { 167 public: 168 virtual ~AudioPortConfig() = default; 169 170 virtual sp<AudioPort> getAudioPort() const = 0; 171 172 virtual status_t applyAudioPortConfig(const struct audio_port_config *config, 173 struct audio_port_config *backupConfig = NULL); 174 175 virtual void toAudioPortConfig(struct audio_port_config *dstConfig, 176 const struct audio_port_config *srcConfig = NULL) const; 177 getSamplingRate()178 unsigned int getSamplingRate() const { return mSamplingRate; } getFormat()179 audio_format_t getFormat() const { return mFormat; } getChannelMask()180 audio_channel_mask_t getChannelMask() const { return mChannelMask; } getId()181 audio_port_handle_t getId() const { return mId; } getFlags()182 audio_io_flags getFlags() const { return mFlags; } 183 184 bool hasGainController(bool canUseForVolume = false) const; 185 186 bool equals(const sp<AudioPortConfig>& other, bool isInput) const; 187 188 status_t writeToParcelable( 189 media::audio::common::AudioPortConfig* parcelable, bool isInput) const; 190 status_t readFromParcelable( 191 const media::audio::common::AudioPortConfig& parcelable, bool isInput); 192 193 protected: 194 unsigned int mSamplingRate = 0u; 195 audio_format_t mFormat = AUDIO_FORMAT_INVALID; 196 audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE; 197 audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE; 198 struct audio_gain_config mGain = { .index = -1 }; 199 union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE }; 200 }; 201 202 } // namespace android 203