1112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie/* 2112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * Copyright (C) 2015 The Android Open Source Project 3112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * 4112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * Licensed under the Apache License, Version 2.0 (the "License"); 5112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * you may not use this file except in compliance with the License. 6112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * You may obtain a copy of the License at 7112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * 8112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * http://www.apache.org/licenses/LICENSE-2.0 9112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * 10112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * Unless required by applicable law or agreed to in writing, software 11112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * distributed under the License is distributed on an "AS IS" BASIS, 12112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * See the License for the specific language governing permissions and 14112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie * limitations under the License. 15112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie */ 16112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 17112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#pragma once 18112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 19112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include "policy.h" 20112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include <utils/String8.h> 21112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include <utils/SortedVector.h> 22112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include <utils/RefBase.h> 23112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include <utils/Errors.h> 24112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include <system/audio.h> 25112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include <cutils/config_utils.h> 26112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 27112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffienamespace android { 28112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 29112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffietypedef SortedVector<uint32_t> SampleRateVector; 30112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffietypedef SortedVector<audio_channel_mask_t> ChannelsVector; 31112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffietypedef Vector<audio_format_t> FormatVector; 32112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 33112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffietemplate <typename T> 34112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiebool operator == (const SortedVector<T> &left, const SortedVector<T> &right); 35112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 36112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffieclass AudioProfile : public virtual RefBase 37112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie{ 38112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiepublic: 39112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie AudioProfile(audio_format_t format, 40112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_channel_mask_t channelMasks, 41112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie uint32_t samplingRate) : 42112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mName(String8("")), 43112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mFormat(format) 44112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 45112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mChannelMasks.add(channelMasks); 46112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mSamplingRates.add(samplingRate); 47112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 48112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 49112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie AudioProfile(audio_format_t format, 50112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie const ChannelsVector &channelMasks, 51112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie const SampleRateVector &samplingRateCollection) : 52112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mName(String8("")), 53112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mFormat(format), 54112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mChannelMasks(channelMasks), 55112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mSamplingRates(samplingRateCollection) 56112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie {} 57112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 58112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_format_t getFormat() const { return mFormat; } 59112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 60112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setChannels(const ChannelsVector &channelMasks) 61112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 62112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (mIsDynamicChannels) { 63112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mChannelMasks = channelMasks; 64112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 65112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 66112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie const ChannelsVector &getChannels() const { return mChannelMasks; } 67112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 68112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setSampleRates(const SampleRateVector &sampleRates) 69112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 70112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (mIsDynamicRate) { 71112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mSamplingRates = sampleRates; 72112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 73112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 74112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie const SampleRateVector &getSampleRates() const { return mSamplingRates; } 75112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 76112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool isValid() const { return hasValidFormat() && hasValidRates() && hasValidChannels(); } 77112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 78112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void clear() 79112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 80112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (mIsDynamicChannels) { 81112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mChannelMasks.clear(); 82112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 83112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (mIsDynamicRate) { 84112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mSamplingRates.clear(); 85112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 86112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 87112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 88112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie inline bool supportsChannels(audio_channel_mask_t channels) const 89112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 90112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return mChannelMasks.indexOf(channels) >= 0; 91112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 92112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie inline bool supportsRate(uint32_t rate) const 93112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 94112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return mSamplingRates.indexOf(rate) >= 0; 95112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 96112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 97112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie status_t checkExact(uint32_t rate, audio_channel_mask_t channels, audio_format_t format) const; 98112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 99112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie status_t checkCompatibleChannelMask(audio_channel_mask_t channelMask, 100112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_channel_mask_t &updatedChannelMask, 101112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_port_type_t portType, 102112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_port_role_t portRole) const; 103112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 104112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie status_t checkCompatibleSamplingRate(uint32_t samplingRate, 105112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie uint32_t &updatedSamplingRate) const; 106112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 107112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasValidFormat() const { return mFormat != AUDIO_FORMAT_DEFAULT; } 108112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasValidRates() const { return !mSamplingRates.isEmpty(); } 109112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasValidChannels() const { return !mChannelMasks.isEmpty(); } 110112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 111112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setDynamicChannels(bool dynamic) { mIsDynamicChannels = dynamic; } 112112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool isDynamicChannels() const { return mIsDynamicChannels; } 113112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 114112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setDynamicRate(bool dynamic) { mIsDynamicRate = dynamic; } 115112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool isDynamicRate() const { return mIsDynamicRate; } 116112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 117112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setDynamicFormat(bool dynamic) { mIsDynamicFormat = dynamic; } 118112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool isDynamicFormat() const { return mIsDynamicFormat; } 119112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 120112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool isDynamic() { return mIsDynamicFormat || mIsDynamicChannels || mIsDynamicRate; } 121112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 122112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void dump(int fd, int spaces) const; 123112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 124112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffieprivate: 125112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie String8 mName; 126112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_format_t mFormat; 127112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie ChannelsVector mChannelMasks; 128112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie SampleRateVector mSamplingRates; 129112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 130112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool mIsDynamicFormat = false; 131112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool mIsDynamicChannels = false; 132112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool mIsDynamicRate = false; 133112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie}; 134112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 135112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 136112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffieclass AudioProfileVector : public Vector<sp<AudioProfile> > 137112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie{ 138112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiepublic: 139112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie ssize_t add(const sp<AudioProfile> &profile) 140112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 141112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie ssize_t index = Vector::add(profile); 142112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry. 143112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // TODO: compareFormats could be a lambda to convert between pointer-to-format to format: 144112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // [](const audio_format_t *format1, const audio_format_t *format2) { 145112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // return compareFormats(*format1, *format2); 146112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // } 147112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sort(compareFormats); 148112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return index; 149112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 150112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 151112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // This API is intended to be used by the policy manager once retrieving capabilities 152112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // for a profile with dynamic format, rate and channels attributes 153112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie ssize_t addProfileFromHal(const sp<AudioProfile> &profileToAdd) 154112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 155112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // Check valid profile to add: 156112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (!profileToAdd->hasValidFormat()) { 157112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return -1; 158112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 159112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) { 160112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie FormatVector formats; 161112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie formats.add(profileToAdd->getFormat()); 162112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie setFormats(FormatVector(formats)); 163112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return 0; 164112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 165112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (!profileToAdd->hasValidChannels() && profileToAdd->hasValidRates()) { 166112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie setSampleRatesFor(profileToAdd->getSampleRates(), profileToAdd->getFormat()); 167112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return 0; 168112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 169112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) { 170112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie setChannelsFor(profileToAdd->getChannels(), profileToAdd->getFormat()); 171112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return 0; 172112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 173112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // Go through the list of profile to avoid duplicates 174112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t profileIndex = 0; profileIndex < size(); profileIndex++) { 175112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie const sp<AudioProfile> &profile = itemAt(profileIndex); 176112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profile->isValid() && profile == profileToAdd) { 177112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // Nothing to do 178112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return profileIndex; 179112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 180112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 181112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal 182112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return add(profileToAdd); 183112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 184112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 185112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> getFirstValidProfile() const 186112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 187112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 188112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (itemAt(i)->isValid()) { 189112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return itemAt(i); 190112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 191112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 192112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return 0; 193112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 194112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 195112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasValidProfile() const { return getFirstValidProfile() != 0; } 196112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 197112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie status_t checkExactProfile(uint32_t samplingRate, audio_channel_mask_t channelMask, 198112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_format_t format) const; 199112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 200112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie status_t checkCompatibleProfile(uint32_t &samplingRate, audio_channel_mask_t &channelMask, 201112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_format_t &format, 202112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_port_type_t portType, 203112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_port_role_t portRole) const; 204112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 205112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie FormatVector getSupportedFormats() const 206112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 207112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie FormatVector supportedFormats; 208112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 209112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (itemAt(i)->hasValidFormat()) { 210112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie supportedFormats.add(itemAt(i)->getFormat()); 211112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 212112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 213112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return supportedFormats; 214112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 215112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 216112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasDynamicProfile() const 217112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 218112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 219112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (itemAt(i)->isDynamic()) { 220112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return true; 221112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 222112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 223112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return false; 224112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 225112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 226112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasDynamicFormat() const 227112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 228112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return getProfileFor(gDynamicFormat) != 0; 229112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 230112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 231112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasDynamicChannelsFor(audio_format_t format) const 232112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 233112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 234112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> profile = itemAt(i); 235112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profile->getFormat() == format && profile->isDynamicChannels()) { 236112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return true; 237112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 238112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 239112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return false; 240112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 241112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 242112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie bool hasDynamicRateFor(audio_format_t format) const 243112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 244112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 245112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> profile = itemAt(i); 246112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profile->getFormat() == format && profile->isDynamicRate()) { 247112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return true; 248112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 249112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 250112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return false; 251112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 252112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 253112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // One audio profile will be added for each format supported by Audio HAL 254112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setFormats(const FormatVector &formats) 255112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 256112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // Only allow to change the format of dynamic profile 257112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> dynamicFormatProfile = getProfileFor(gDynamicFormat); 258112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (dynamicFormatProfile == 0) { 259112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return; 260112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 261112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < formats.size(); i++) { 262112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> profile = new AudioProfile(formats[i], 263112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie dynamicFormatProfile->getChannels(), 264112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie dynamicFormatProfile->getSampleRates()); 265112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->setDynamicFormat(true); 266112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels()); 267112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->setDynamicRate(dynamicFormatProfile->isDynamicRate()); 268112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie add(profile); 269112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 270112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 271112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 27220eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent void clearProfiles() 27320eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent { 27420eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent for (size_t i = size(); i != 0; ) { 27520eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent sp<AudioProfile> profile = itemAt(--i); 27620eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent if (profile->isDynamicFormat() && profile->hasValidFormat()) { 27720eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent removeAt(i); 27820eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent continue; 27920eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent } 28020eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent profile->clear(); 28120eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent } 28220eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent } 28320eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent 28420eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent void dump(int fd, int spaces) const 28520eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent { 28620eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent const size_t SIZE = 256; 28720eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent char buffer[SIZE]; 28820eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent 28920eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent snprintf(buffer, SIZE, "%*s- Profiles:\n", spaces, ""); 29020eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent write(fd, buffer, strlen(buffer)); 29120eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent for (size_t i = 0; i < size(); i++) { 29220eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent snprintf(buffer, SIZE, "%*sProfile %zu:", spaces + 4, "", i); 29320eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent write(fd, buffer, strlen(buffer)); 29420eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent itemAt(i)->dump(fd, spaces + 8); 29520eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent } 29620eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent } 29720eb3a4340a1f1f6e978a23527daff080140db1aEric Laurent 29820eb3a4340a1f1f6e978a23527daff080140db1aEric Laurentprivate: 299112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setSampleRatesFor(const SampleRateVector &sampleRates, audio_format_t format) 300112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 301112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 302112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> profile = itemAt(i); 303112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profile->getFormat() == format && profile->isDynamicRate()) { 304112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profile->hasValidRates()) { 305112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // Need to create a new profile with same format 306112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> profileToAdd = new AudioProfile(format, profile->getChannels(), 307112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sampleRates); 308112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profileToAdd->setDynamicFormat(true); // need to set to allow cleaning 309112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie add(profileToAdd); 310112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } else { 311112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->setSampleRates(sampleRates); 312112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 313112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return; 314112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 315112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 316112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 317112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 318112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie void setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format) 319112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 320112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 321112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> profile = itemAt(i); 322112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profile->getFormat() == format && profile->isDynamicChannels()) { 323112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (profile->hasValidChannels()) { 324112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // Need to create a new profile with same format 325112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> profileToAdd = new AudioProfile(format, channelMasks, 326112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->getSampleRates()); 327112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profileToAdd->setDynamicFormat(true); // need to set to allow cleaning 328112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie add(profileToAdd); 329112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } else { 330112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->setChannels(channelMasks); 331112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 332112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return; 333112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 334112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 335112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 336112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 337112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie sp<AudioProfile> getProfileFor(audio_format_t format) const 338112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 339112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie for (size_t i = 0; i < size(); i++) { 340112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (itemAt(i)->getFormat() == format) { 341112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return itemAt(i); 342112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 343112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 344112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return 0; 345112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 346112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 347112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie static int compareFormats(const sp<AudioProfile> *profile1, const sp<AudioProfile> *profile2); 348112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie}; 349112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 350112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiebool operator == (const AudioProfile &left, const AudioProfile &right); 351112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie 352112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie}; // namespace android 353