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