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