• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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