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