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