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