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 "AudioPort.h" 20 #include "DeviceDescriptor.h" 21 #include <utils/String8.h> 22 #include <system/audio.h> 23 24 namespace android { 25 26 class HwModule; 27 28 // the IOProfile class describes the capabilities of an output or input stream. 29 // It is currently assumed that all combination of listed parameters are supported. 30 // It is used by the policy manager to determine if an output or input is suitable for 31 // a given use case, open/close it accordingly and connect/disconnect audio tracks 32 // to/from it. 33 class IOProfile : public AudioPort 34 { 35 public: IOProfile(const String8 & name,audio_port_role_t role)36 IOProfile(const String8 &name, audio_port_role_t role) 37 : AudioPort(name, AUDIO_PORT_TYPE_MIX, role), 38 maxOpenCount(1), 39 curOpenCount(0), 40 maxActiveCount(1), 41 curActiveCount(0) {} 42 43 // For a Profile aka MixPort, tag name and name are equivalent. getTagName()44 virtual const String8 getTagName() const { return getName(); } 45 46 // FIXME: this is needed because shared MMAP stream clients use the same audio session. 47 // Once capture clients are tracked individually and not per session this can be removed 48 // MMAP no IRQ input streams do not have the default limitation of one active client 49 // max as they can be used in shared mode by the same application. 50 // NOTE: this works for explicit values set in audio_policy_configuration.xml because 51 // flags are parsed before maxActiveCount by the serializer. setFlags(uint32_t flags)52 void setFlags(uint32_t flags) override 53 { 54 AudioPort::setFlags(flags); 55 if (getRole() == AUDIO_PORT_ROLE_SINK && (flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) { 56 maxActiveCount = 0; 57 } 58 } 59 60 /** 61 * @brief isCompatibleProfile: This method is used for input and direct output, 62 * and is not used for other output. 63 * Checks if the IO profile is compatible with specified parameters. 64 * For input, flags is interpreted as audio_input_flags_t. 65 * TODO: merge audio_output_flags_t and audio_input_flags_t. 66 * 67 * @param devices vector of devices to be checked for compatibility 68 * @param samplingRate to be checked for compatibility. Must be specified 69 * @param updatedSamplingRate if non-NULL, it is assigned the actual sample rate. 70 * @param format to be checked for compatibility. Must be specified 71 * @param updatedFormat if non-NULL, it is assigned the actual format 72 * @param channelMask to be checked for compatibility. Must be specified 73 * @param updatedChannelMask if non-NULL, it is assigned the actual channel mask 74 * @param flags to be checked for compatibility 75 * @param exactMatchRequiredForInputFlags true if exact match is required on flags 76 * @return true if the profile is compatible, false otherwise. 77 */ 78 bool isCompatibleProfile(const DeviceVector &devices, 79 uint32_t samplingRate, 80 uint32_t *updatedSamplingRate, 81 audio_format_t format, 82 audio_format_t *updatedFormat, 83 audio_channel_mask_t channelMask, 84 audio_channel_mask_t *updatedChannelMask, 85 // FIXME parameter type 86 uint32_t flags, 87 bool exactMatchRequiredForInputFlags = false) const; 88 89 void dump(String8 *dst) const; 90 void log(); 91 hasSupportedDevices()92 bool hasSupportedDevices() const { return !mSupportedDevices.isEmpty(); } 93 supportsDeviceTypes(audio_devices_t device)94 bool supportsDeviceTypes(audio_devices_t device) const 95 { 96 if (audio_is_output_devices(device)) { 97 if (deviceSupportsEncodedFormats(device)) { 98 return mSupportedDevices.types() & device; 99 } 100 return false; 101 } 102 return mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN); 103 } 104 105 /** 106 * @brief supportsDevice 107 * @param device to be checked against 108 * forceCheckOnAddress if true, check on type and address whatever the type, otherwise 109 * the address enforcement is limited to "offical devices" that distinguishe on address 110 * @return true if the device is supported by type (for non bus / remote submix devices), 111 * true if the device is supported (both type and address) for bus / remote submix 112 * false otherwise 113 */ 114 bool supportsDevice(const sp<DeviceDescriptor> &device, bool forceCheckOnAddress = false) const 115 { 116 if (!device_distinguishes_on_address(device->type()) && !forceCheckOnAddress) { 117 return supportsDeviceTypes(device->type()); 118 } 119 return mSupportedDevices.contains(device); 120 } 121 deviceSupportsEncodedFormats(audio_devices_t device)122 bool deviceSupportsEncodedFormats(audio_devices_t device) const 123 { 124 if (device == AUDIO_DEVICE_NONE) { 125 return true; // required for isOffloadSupported() check 126 } 127 DeviceVector deviceList = 128 mSupportedDevices.getDevicesFromTypeMask(device); 129 if (!deviceList.empty()) { 130 return deviceList.itemAt(0)->hasCurrentEncodedFormat(); 131 } 132 return false; 133 } 134 clearSupportedDevices()135 void clearSupportedDevices() { mSupportedDevices.clear(); } addSupportedDevice(const sp<DeviceDescriptor> & device)136 void addSupportedDevice(const sp<DeviceDescriptor> &device) 137 { 138 mSupportedDevices.add(device); 139 } removeSupportedDevice(const sp<DeviceDescriptor> & device)140 void removeSupportedDevice(const sp<DeviceDescriptor> &device) 141 { 142 mSupportedDevices.remove(device); 143 } setSupportedDevices(const DeviceVector & devices)144 void setSupportedDevices(const DeviceVector &devices) 145 { 146 mSupportedDevices = devices; 147 } 148 getSupportedDevices()149 const DeviceVector &getSupportedDevices() const { return mSupportedDevices; } 150 canOpenNewIo()151 bool canOpenNewIo() { 152 if (maxOpenCount == 0 || curOpenCount < maxOpenCount) { 153 return true; 154 } 155 return false; 156 } 157 canStartNewIo()158 bool canStartNewIo() { 159 if (maxActiveCount == 0 || curActiveCount < maxActiveCount) { 160 return true; 161 } 162 return false; 163 } 164 165 // Maximum number of input or output streams that can be simultaneously opened for this profile. 166 // By convention 0 means no limit. To respect legacy behavior, initialized to 1 for output 167 // profiles and 0 for input profiles 168 uint32_t maxOpenCount; 169 // Number of streams currently opened for this profile. 170 uint32_t curOpenCount; 171 // Maximum number of input or output streams that can be simultaneously active for this profile. 172 // By convention 0 means no limit. To respect legacy behavior, initialized to 0 for output 173 // profiles and 1 for input profiles 174 uint32_t maxActiveCount; 175 // Number of streams currently active for this profile. This is not the number of active clients 176 // (AudioTrack or AudioRecord) but the number of active HAL streams. 177 uint32_t curActiveCount; 178 179 private: 180 DeviceVector mSupportedDevices; // supported devices: this input/output can be routed from/to 181 }; 182 183 class InputProfile : public IOProfile 184 { 185 public: InputProfile(const String8 & name)186 explicit InputProfile(const String8 &name) : IOProfile(name, AUDIO_PORT_ROLE_SINK) {} 187 }; 188 189 class OutputProfile : public IOProfile 190 { 191 public: OutputProfile(const String8 & name)192 explicit OutputProfile(const String8 &name) : IOProfile(name, AUDIO_PORT_ROLE_SOURCE) {} 193 }; 194 195 } // namespace android 196