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 "AudioProfile.h"
21#include <utils/String8.h>
22#include <utils/Vector.h>
23#include <utils/RefBase.h>
24#include <utils/Errors.h>
25#include <system/audio.h>
26#include <cutils/config_utils.h>
27
28namespace android {
29
30class HwModule;
31class AudioGain;
32class AudioRoute;
33typedef Vector<sp<AudioGain> > AudioGainCollection;
34
35class AudioPort : public virtual RefBase
36{
37public:
38    AudioPort(const String8& name, audio_port_type_t type,  audio_port_role_t role) :
39        mName(name), mType(type), mRole(role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
40
41    virtual ~AudioPort() {}
42
43    void setName(const String8 &name) { mName = name; }
44    const String8 &getName() const { return mName; }
45
46    audio_port_type_t getType() const { return mType; }
47    audio_port_role_t getRole() const { return mRole; }
48
49    virtual const String8 getTagName() const = 0;
50
51    void setGains(const AudioGainCollection &gains) { mGains = gains; }
52    const AudioGainCollection &getGains() const { return mGains; }
53
54    void setFlags(uint32_t flags)
55    {
56        //force direct flag if offload flag is set: offloading implies a direct output stream
57        // and all common behaviors are driven by checking only the direct flag
58        // this should normally be set appropriately in the policy configuration file
59        if (mRole == AUDIO_PORT_ROLE_SOURCE && (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
60            flags |= AUDIO_OUTPUT_FLAG_DIRECT;
61        }
62        mFlags = flags;
63    }
64    uint32_t getFlags() const { return mFlags; }
65
66    virtual void attach(const sp<HwModule>& module);
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    virtual void toAudioPort(struct audio_port *port) const;
73
74    virtual void importAudioPort(const sp<AudioPort> port);
75
76    void addAudioProfile(const sp<AudioProfile> &profile) { mProfiles.add(profile); }
77
78    void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
79    AudioProfileVector &getAudioProfiles() { return mProfiles; }
80
81    bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
82
83    bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
84
85    // searches for an exact match
86    status_t checkExactAudioProfile(uint32_t samplingRate,
87                                    audio_channel_mask_t channelMask,
88                                    audio_format_t format) const
89    {
90        return mProfiles.checkExactProfile(samplingRate, channelMask, format);
91    }
92
93    // searches for a compatible match, currently implemented for input
94    // parameters are input|output, returned value is the best match.
95    status_t checkCompatibleAudioProfile(uint32_t &samplingRate,
96                                         audio_channel_mask_t &channelMask,
97                                         audio_format_t &format) const
98    {
99        return mProfiles.checkCompatibleProfile(samplingRate, channelMask, format, mType, mRole);
100    }
101
102    void clearAudioProfiles() { return mProfiles.clearProfiles(); }
103
104    status_t checkGain(const struct audio_gain_config *gainConfig, int index) const;
105
106    void pickAudioProfile(uint32_t &samplingRate,
107                          audio_channel_mask_t &channelMask,
108                          audio_format_t &format) const;
109
110    static const audio_format_t sPcmFormatCompareTable[];
111
112    static int compareFormats(audio_format_t format1, audio_format_t format2);
113
114    // Used to select an audio HAL output stream with a sample format providing the
115    // less degradation for a given AudioTrack sample format.
116    static bool isBetterFormatMatch(audio_format_t newFormat,
117                                        audio_format_t currentFormat,
118                                        audio_format_t targetFormat);
119
120    audio_module_handle_t getModuleHandle() const;
121    uint32_t getModuleVersion() const;
122    const char *getModuleName() const;
123
124    bool useInputChannelMask() const
125    {
126        return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) ||
127                ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK));
128    }
129
130    inline bool isDirectOutput() const
131    {
132        return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
133                (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
134    }
135
136    void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
137    const AudioRouteVector &getRoutes() const { return mRoutes; }
138
139    void dump(int fd, int spaces, bool verbose = true) const;
140    void log(const char* indent) const;
141
142    AudioGainCollection mGains; // gain controllers
143    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
144
145private:
146    void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
147    void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
148
149    String8  mName;
150    audio_port_type_t mType;
151    audio_port_role_t mRole;
152    uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...).
153    AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
154    AudioRouteVector mRoutes; // Routes involving this port
155    static volatile int32_t mNextUniqueId;
156};
157
158class AudioPortConfig : public virtual RefBase
159{
160public:
161    AudioPortConfig();
162    virtual ~AudioPortConfig() {}
163
164    status_t applyAudioPortConfig(const struct audio_port_config *config,
165                                  struct audio_port_config *backupConfig = NULL);
166    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
167                                   const struct audio_port_config *srcConfig = NULL) const = 0;
168    virtual sp<AudioPort> getAudioPort() const = 0;
169    uint32_t mSamplingRate;
170    audio_format_t mFormat;
171    audio_channel_mask_t mChannelMask;
172    struct audio_gain_config mGain;
173};
174
175}; // namespace android
176