1 /*
2  * Copyright (C) 2015 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 "AudioCollections.h"
20 #include "AudioProfile.h"
21 #include <utils/String8.h>
22 #include <utils/Vector.h>
23 #include <utils/RefBase.h>
24 #include <utils/Errors.h>
25 #include <system/audio.h>
26 #include <cutils/config_utils.h>
27 
28 namespace android {
29 
30 class HwModule;
31 class AudioGain;
32 class AudioRoute;
33 typedef Vector<sp<AudioGain> > AudioGainCollection;
34 
35 class AudioPort : public virtual RefBase
36 {
37 public:
AudioPort(const String8 & name,audio_port_type_t type,audio_port_role_t role)38     AudioPort(const String8& name, audio_port_type_t type,  audio_port_role_t role) :
39         mName(name), mType(type), mRole(role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
40 
~AudioPort()41     virtual ~AudioPort() {}
42 
setName(const String8 & name)43     void setName(const String8 &name) { mName = name; }
getName()44     const String8 &getName() const { return mName; }
45 
getType()46     audio_port_type_t getType() const { return mType; }
getRole()47     audio_port_role_t getRole() const { return mRole; }
48 
49     virtual const String8 getTagName() const = 0;
50 
setGains(const AudioGainCollection & gains)51     void setGains(const AudioGainCollection &gains) { mGains = gains; }
getGains()52     const AudioGainCollection &getGains() const { return mGains; }
53 
setFlags(uint32_t flags)54     void setFlags(uint32_t flags)
55     {
56         //force direct flag if offload flag is set: offloading implies a direct output stream
57         // and all common behaviors are driven by checking only the direct flag
58         // this should normally be set appropriately in the policy configuration file
59         if (mRole == AUDIO_PORT_ROLE_SOURCE && (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
60             flags |= AUDIO_OUTPUT_FLAG_DIRECT;
61         }
62         mFlags = flags;
63     }
getFlags()64     uint32_t getFlags() const { return mFlags; }
65 
66     virtual void attach(const sp<HwModule>& module);
isAttached()67     bool isAttached() { return mModule != 0; }
68 
69     // Audio port IDs are in a different namespace than AudioFlinger unique IDs
70     static audio_port_handle_t getNextUniqueId();
71 
72     virtual void toAudioPort(struct audio_port *port) const;
73 
74     virtual void importAudioPort(const sp<AudioPort> port);
75 
addAudioProfile(const sp<AudioProfile> & profile)76     void addAudioProfile(const sp<AudioProfile> &profile) { mProfiles.add(profile); }
77 
setAudioProfiles(const AudioProfileVector & profiles)78     void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
getAudioProfiles()79     AudioProfileVector &getAudioProfiles() { return mProfiles; }
80 
hasValidAudioProfile()81     bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
82 
hasDynamicAudioProfile()83     bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
84 
85     // searches for an exact match
checkExactAudioProfile(uint32_t samplingRate,audio_channel_mask_t channelMask,audio_format_t format)86     status_t checkExactAudioProfile(uint32_t samplingRate,
87                                     audio_channel_mask_t channelMask,
88                                     audio_format_t format) const
89     {
90         return mProfiles.checkExactProfile(samplingRate, channelMask, format);
91     }
92 
93     // searches for a compatible match, currently implemented for input
94     // parameters are input|output, returned value is the best match.
checkCompatibleAudioProfile(uint32_t & samplingRate,audio_channel_mask_t & channelMask,audio_format_t & format)95     status_t checkCompatibleAudioProfile(uint32_t &samplingRate,
96                                          audio_channel_mask_t &channelMask,
97                                          audio_format_t &format) const
98     {
99         return mProfiles.checkCompatibleProfile(samplingRate, channelMask, format, mType, mRole);
100     }
101 
clearAudioProfiles()102     void clearAudioProfiles() { return mProfiles.clearProfiles(); }
103 
104     status_t checkGain(const struct audio_gain_config *gainConfig, int index) const;
105 
106     void pickAudioProfile(uint32_t &samplingRate,
107                           audio_channel_mask_t &channelMask,
108                           audio_format_t &format) const;
109 
110     static const audio_format_t sPcmFormatCompareTable[];
111 
112     static int compareFormats(audio_format_t format1, audio_format_t format2);
113 
114     // Used to select an audio HAL output stream with a sample format providing the
115     // less degradation for a given AudioTrack sample format.
116     static bool isBetterFormatMatch(audio_format_t newFormat,
117                                         audio_format_t currentFormat,
118                                         audio_format_t targetFormat);
119 
120     audio_module_handle_t getModuleHandle() const;
121     uint32_t getModuleVersion() const;
122     const char *getModuleName() const;
123 
useInputChannelMask()124     bool useInputChannelMask() const
125     {
126         return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) ||
127                 ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK));
128     }
129 
isDirectOutput()130     inline bool isDirectOutput() const
131     {
132         return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
133                 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
134     }
135 
addRoute(const sp<AudioRoute> & route)136     void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
getRoutes()137     const AudioRouteVector &getRoutes() const { return mRoutes; }
138 
139     void dump(int fd, int spaces, bool verbose = true) const;
140     void log(const char* indent) const;
141 
142     AudioGainCollection mGains; // gain controllers
143     sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
144 
145 private:
146     void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
147     void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
148 
149     String8  mName;
150     audio_port_type_t mType;
151     audio_port_role_t mRole;
152     uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...).
153     AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
154     AudioRouteVector mRoutes; // Routes involving this port
155     static volatile int32_t mNextUniqueId;
156 };
157 
158 class AudioPortConfig : public virtual RefBase
159 {
160 public:
161     AudioPortConfig();
~AudioPortConfig()162     virtual ~AudioPortConfig() {}
163 
164     status_t applyAudioPortConfig(const struct audio_port_config *config,
165                                   struct audio_port_config *backupConfig = NULL);
166     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
167                                    const struct audio_port_config *srcConfig = NULL) const = 0;
168     virtual sp<AudioPort> getAudioPort() const = 0;
169     uint32_t mSamplingRate;
170     audio_format_t mFormat;
171     audio_channel_mask_t mChannelMask;
172     struct audio_gain_config mGain;
173 };
174 
175 }; // namespace android
176