• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "AudioProfileVectorHelper.h"
21 #include "HandleGenerator.h"
22 #include <media/AudioGain.h>
23 #include <media/AudioPort.h>
24 #include <utils/String8.h>
25 #include <utils/Vector.h>
26 #include <utils/RefBase.h>
27 #include <utils/Errors.h>
28 #include <system/audio.h>
29 #include <cutils/config_utils.h>
30 
31 namespace android {
32 
33 class HwModule;
34 class AudioRoute;
35 
36 class PolicyAudioPort : public virtual RefBase, private HandleGenerator<audio_port_handle_t>
37 {
38 public:
PolicyAudioPort()39     PolicyAudioPort() : mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
40 
41     virtual ~PolicyAudioPort() = default;
42 
43     virtual const std::string getTagName() const = 0;
44 
equals(const sp<PolicyAudioPort> & right)45     bool equals(const sp<PolicyAudioPort> &right) const
46     {
47         return right != 0 && getTagName() == right->getTagName();
48     }
49 
50     virtual sp<AudioPort> asAudioPort() const = 0;
51 
setFlags(uint32_t flags)52     virtual void setFlags(uint32_t flags)
53     {
54         //force direct flag if offload flag is set: offloading implies a direct output stream
55         // and all common behaviors are driven by checking only the direct flag
56         // this should normally be set appropriately in the policy configuration file
57         if (asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE &&
58                 (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
59             flags |= AUDIO_OUTPUT_FLAG_DIRECT;
60         }
61         mFlags = flags;
62     }
getFlags()63     uint32_t getFlags() const { return mFlags; }
64 
65     virtual void attach(const sp<HwModule>& module);
66     virtual void detach();
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     // searches for an exact match
73     virtual status_t checkExactAudioProfile(const struct audio_port_config *config) const;
74 
75     // searches for a compatible match, currently implemented for input
76     // parameters are input|output, returned value is the best match.
checkCompatibleAudioProfile(uint32_t & samplingRate,audio_channel_mask_t & channelMask,audio_format_t & format)77     status_t checkCompatibleAudioProfile(uint32_t &samplingRate,
78                                          audio_channel_mask_t &channelMask,
79                                          audio_format_t &format) const
80     {
81         return checkCompatibleProfile(
82                 asAudioPort()->getAudioProfiles(), samplingRate, channelMask, format,
83                 asAudioPort()->getType(), asAudioPort()->getRole());
84     }
85 
86     void pickAudioProfile(uint32_t &samplingRate,
87                           audio_channel_mask_t &channelMask,
88                           audio_format_t &format) const;
89 
90     static const audio_format_t sPcmFormatCompareTable[];
91 
92     static int compareFormats(audio_format_t format1, audio_format_t format2);
93 
94     // Used to select an audio HAL output stream with a sample format providing the
95     // less degradation for a given AudioTrack sample format.
96     static bool isBetterFormatMatch(audio_format_t newFormat,
97                                     audio_format_t currentFormat,
98                                     audio_format_t targetFormat);
99     static uint32_t formatDistance(audio_format_t format1,
100                                    audio_format_t format2);
101     static const uint32_t kFormatDistanceMax = 4;
102 
103     audio_module_handle_t getModuleHandle() const;
104     uint32_t getModuleVersionMajor() const;
105     const char *getModuleName() const;
getModule()106     sp<HwModule> getModule() const { return mModule; }
107 
isDirectOutput()108     inline bool isDirectOutput() const
109     {
110         return (asAudioPort()->getType() == AUDIO_PORT_TYPE_MIX) &&
111                 (asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE) &&
112                 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
113     }
114 
isMmap()115     inline bool isMmap() const
116     {
117         return (asAudioPort()->getType() == AUDIO_PORT_TYPE_MIX)
118                 && (((asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE) &&
119                         ((mFlags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) != 0))
120                     || ((asAudioPort()->getRole() == AUDIO_PORT_ROLE_SINK) &&
121                         ((mFlags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0)));
122     }
123 
addRoute(const sp<AudioRoute> & route)124     void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
getRoutes()125     const AudioRouteVector &getRoutes() const { return mRoutes; }
126 
127 private:
128     void pickChannelMask(audio_channel_mask_t &channelMask,
129                          const ChannelMaskSet &channelMasks) const;
130     void pickSamplingRate(uint32_t &rate, const SampleRateSet &samplingRates) const;
131 
132     uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...).
133     sp<HwModule> mModule;     // audio HW module exposing this I/O stream
134     AudioRouteVector mRoutes; // Routes involving this port
135 };
136 
137 class PolicyAudioPortConfig : public virtual RefBase
138 {
139 public:
140     virtual ~PolicyAudioPortConfig() = default;
141 
142     virtual sp<PolicyAudioPort> getPolicyAudioPort() const = 0;
143 
144     status_t validationBeforeApplyConfig(const struct audio_port_config *config) const;
145 
applyPolicyAudioPortConfig(const struct audio_port_config * config)146     void applyPolicyAudioPortConfig(const struct audio_port_config *config) {
147         if (config->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
148             mFlags = config->flags;
149         }
150     }
151 
152     void toPolicyAudioPortConfig(
153             struct audio_port_config *dstConfig,
154             const struct audio_port_config *srcConfig = NULL) const;
155 
156 
hasSameHwModuleAs(const sp<PolicyAudioPortConfig> & other)157     virtual bool hasSameHwModuleAs(const sp<PolicyAudioPortConfig>& other) const {
158         return (other.get() != nullptr) && (other->getPolicyAudioPort().get() != nullptr) &&
159                 (getPolicyAudioPort().get() != nullptr) &&
160                 (other->getPolicyAudioPort()->getModuleHandle() ==
161                         getPolicyAudioPort()->getModuleHandle());
162     }
163 
164     union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE };
165 };
166 
167 } // namespace android
168