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/AudioPortFw.h> 23 #include <android/media/AudioPortConfigFw.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 { 52 return useInputChannelMask() ? static_cast<uint32_t>(mFlags.input) 53 : static_cast<uint32_t>(mFlags.output); 54 } 55 setGains(const AudioGains & gains)56 void setGains(const AudioGains &gains) { mGains = gains; } getGains()57 const AudioGains &getGains() const { return mGains; } 58 59 virtual void toAudioPort(struct audio_port *port) const; 60 61 virtual void toAudioPort(struct audio_port_v7 *port) const; 62 addAudioProfile(const sp<AudioProfile> & profile)63 virtual void addAudioProfile(const sp<AudioProfile> &profile) { 64 mProfiles.add(profile); 65 } clearAudioProfiles()66 virtual void clearAudioProfiles() { 67 mProfiles.clearProfiles(); 68 } 69 hasValidAudioProfile()70 bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); } 71 hasDynamicAudioProfile()72 bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); } 73 setAudioProfiles(const AudioProfileVector & profiles)74 void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; } getAudioProfiles()75 AudioProfileVector &getAudioProfiles() { return mProfiles; } 76 setExtraAudioDescriptors(const std::vector<media::audio::common::ExtraAudioDescriptor> & extraAudioDescriptors)77 void setExtraAudioDescriptors( 78 const std::vector<media::audio::common::ExtraAudioDescriptor>& extraAudioDescriptors) { 79 mExtraAudioDescriptors = extraAudioDescriptors; 80 } getExtraAudioDescriptors()81 std::vector<media::audio::common::ExtraAudioDescriptor> &getExtraAudioDescriptors() { 82 return mExtraAudioDescriptors; 83 } 84 85 virtual void importAudioPort(const sp<AudioPort>& port, bool force = false); 86 87 virtual void importAudioPort(const audio_port_v7& port); 88 checkGain(const struct audio_gain_config * gainConfig,int index)89 status_t checkGain(const struct audio_gain_config *gainConfig, int index) const { 90 if (index < 0 || (size_t)index >= mGains.size()) { 91 return BAD_VALUE; 92 } 93 return mGains[index]->checkConfig(gainConfig); 94 } 95 useInputChannelMask()96 bool useInputChannelMask() const 97 { 98 return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) || 99 ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK)); 100 } 101 isDirectOutput()102 bool isDirectOutput() const 103 { 104 return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 105 ((mFlags.output & AUDIO_OUTPUT_FLAG_DIRECT) != 0); 106 } 107 isMmap()108 bool isMmap() const 109 { 110 return (mType == AUDIO_PORT_TYPE_MIX) 111 && (((mRole == AUDIO_PORT_ROLE_SOURCE) && 112 ((mFlags.output & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) != 0)) 113 || ((mRole == AUDIO_PORT_ROLE_SINK) && 114 ((mFlags.input & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0))); 115 } 116 117 void dump(std::string *dst, int spaces, 118 const char* extraInfo = nullptr, bool verbose = true) const; 119 120 void log(const char* indent) const; 121 122 bool equals(const sp<AudioPort>& other) const; 123 124 status_t writeToParcelable(media::AudioPortFw* parcelable) const; 125 status_t readFromParcelable(const media::AudioPortFw& parcelable); 126 127 AudioGains mGains; // gain controllers 128 // Maximum number of input or output streams that can be simultaneously 129 // opened for this profile. By convention 0 means no limit. To respect 130 // legacy behavior, initialized to 1 for output profiles and 0 for input 131 // profiles 132 // FIXME: IOProfile code used the same value for both cases. 133 uint32_t maxOpenCount = 1; 134 // Maximum number of input or output streams that can be simultaneously 135 // active for this profile. By convention 0 means no limit. To respect 136 // legacy behavior, initialized to 0 for output profiles and 1 for input 137 // profiles 138 // FIXME: IOProfile code used the same value for both cases. 139 uint32_t maxActiveCount = 1; 140 // Mute duration while changing device on this output profile. 141 uint32_t recommendedMuteDurationMs = 0; 142 143 protected: 144 std::string mName; 145 audio_port_type_t mType; 146 audio_port_role_t mRole; 147 AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels) 148 149 // Audio capabilities that are defined by hardware descriptors when the format is unrecognized 150 // by the platform, e.g. short audio descriptor in EDID for HDMI. 151 std::vector<media::audio::common::ExtraAudioDescriptor> mExtraAudioDescriptors; 152 union audio_io_flags mFlags = { .output = AUDIO_OUTPUT_FLAG_NONE }; 153 private: 154 template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value 155 || std::is_same<T, struct audio_port_v7>::value, int> = 0> toAudioPortBase(T * port)156 void toAudioPortBase(T* port) const { 157 port->role = mRole; 158 port->type = mType; 159 strlcpy(port->name, mName.c_str(), AUDIO_PORT_MAX_NAME_LEN); 160 port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS); 161 for (size_t i = 0; i < port->num_gains; i++) { 162 port->gains[i] = mGains[i]->getGain(); 163 } 164 } 165 }; 166 167 168 class AudioPortConfig : public virtual RefBase 169 { 170 public: 171 virtual ~AudioPortConfig() = default; 172 173 virtual sp<AudioPort> getAudioPort() const = 0; 174 175 virtual status_t applyAudioPortConfig(const struct audio_port_config *config, 176 struct audio_port_config *backupConfig = NULL); 177 178 virtual void toAudioPortConfig(struct audio_port_config *dstConfig, 179 const struct audio_port_config *srcConfig = NULL) const; 180 getSamplingRate()181 unsigned int getSamplingRate() const { return mSamplingRate; } getFormat()182 audio_format_t getFormat() const { return mFormat; } getChannelMask()183 audio_channel_mask_t getChannelMask() const { return mChannelMask; } getId()184 audio_port_handle_t getId() const { return mId; } getFlags()185 audio_io_flags getFlags() const { return mFlags; } 186 187 bool hasGainController(bool canUseForVolume = false) const; 188 189 bool equals(const sp<AudioPortConfig>& other, bool isInput) const; 190 191 status_t writeToParcelable( 192 media::audio::common::AudioPortConfig* parcelable, bool isInput) const; 193 status_t readFromParcelable( 194 const media::audio::common::AudioPortConfig& parcelable, bool isInput); 195 196 protected: 197 unsigned int mSamplingRate = 0u; 198 audio_format_t mFormat = AUDIO_FORMAT_INVALID; 199 audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE; 200 audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE; 201 struct audio_gain_config mGain = { .index = -1 }; 202 union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE }; 203 }; 204 205 } // namespace android 206