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((role == AUDIO_PORT_ROLE_SOURCE) ? 1 : 0),
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     // This method is used for input and direct output, and is not used for other output.
61     // If parameter updatedSamplingRate is non-NULL, it is assigned the actual sample rate.
62     // For input, flags is interpreted as audio_input_flags_t.
63     // TODO: merge audio_output_flags_t and audio_input_flags_t.
64     bool isCompatibleProfile(audio_devices_t device,
65                              const String8& address,
66                              uint32_t samplingRate,
67                              uint32_t *updatedSamplingRate,
68                              audio_format_t format,
69                              audio_format_t *updatedFormat,
70                              audio_channel_mask_t channelMask,
71                              audio_channel_mask_t *updatedChannelMask,
72                              // FIXME parameter type
73                              uint32_t flags,
74                              bool exactMatchRequiredForInputFlags = false) const;
75 
76     void dump(int fd);
77     void log();
78 
hasSupportedDevices()79     bool hasSupportedDevices() const { return !mSupportedDevices.isEmpty(); }
80 
supportDevice(audio_devices_t device)81     bool supportDevice(audio_devices_t device) const
82     {
83         if (audio_is_output_devices(device)) {
84             return mSupportedDevices.types() & device;
85         }
86         return mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN);
87     }
88 
supportDeviceAddress(const String8 & address)89     bool supportDeviceAddress(const String8 &address) const
90     {
91         return mSupportedDevices[0]->mAddress == address;
92     }
93 
94     // chose first device present in mSupportedDevices also part of deviceType
getSupportedDeviceForType(audio_devices_t deviceType)95     audio_devices_t getSupportedDeviceForType(audio_devices_t deviceType) const
96     {
97         for (size_t k = 0; k  < mSupportedDevices.size(); k++) {
98             audio_devices_t profileType = mSupportedDevices[k]->type();
99             if (profileType & deviceType) {
100                 return profileType;
101             }
102         }
103         return AUDIO_DEVICE_NONE;
104     }
105 
getSupportedDevicesType()106     audio_devices_t getSupportedDevicesType() const { return mSupportedDevices.types(); }
107 
clearSupportedDevices()108     void clearSupportedDevices() { mSupportedDevices.clear(); }
addSupportedDevice(const sp<DeviceDescriptor> & device)109     void addSupportedDevice(const sp<DeviceDescriptor> &device)
110     {
111         mSupportedDevices.add(device);
112     }
113 
setSupportedDevices(const DeviceVector & devices)114     void setSupportedDevices(const DeviceVector &devices)
115     {
116         mSupportedDevices = devices;
117     }
118 
getSupportedDeviceByAddress(audio_devices_t type,String8 address)119     sp<DeviceDescriptor> getSupportedDeviceByAddress(audio_devices_t type, String8 address) const
120     {
121         return mSupportedDevices.getDevice(type, address);
122     }
123 
getSupportedDevices()124     const DeviceVector &getSupportedDevices() const { return mSupportedDevices; }
125 
canOpenNewIo()126     bool canOpenNewIo() {
127         if (maxOpenCount == 0 || curOpenCount < maxOpenCount) {
128             return true;
129         }
130         return false;
131     }
132 
canStartNewIo()133     bool canStartNewIo() {
134         if (maxActiveCount == 0 || curActiveCount < maxActiveCount) {
135             return true;
136         }
137         return false;
138     }
139 
140     // Maximum number of input or output streams that can be simultaneously opened for this profile.
141     // By convention 0 means no limit. To respect legacy behavior, initialized to 1 for output
142     // profiles and 0 for input profiles
143     uint32_t     maxOpenCount;
144     // Number of streams currently opened for this profile.
145     uint32_t     curOpenCount;
146     // Maximum number of input or output streams that can be simultaneously active for this profile.
147     // By convention 0 means no limit. To respect legacy behavior, initialized to 0 for output
148     // profiles and 1 for input profiles
149     uint32_t     maxActiveCount;
150     // Number of streams currently active for this profile. This is not the number of active clients
151     // (AudioTrack or AudioRecord) but the number of active HAL streams.
152     uint32_t     curActiveCount;
153 
154 private:
155     DeviceVector mSupportedDevices; // supported devices: this input/output can be routed from/to
156 };
157 
158 class InputProfile : public IOProfile
159 {
160 public:
InputProfile(const String8 & name)161     explicit InputProfile(const String8 &name) : IOProfile(name, AUDIO_PORT_ROLE_SINK) {}
162 };
163 
164 class OutputProfile : public IOProfile
165 {
166 public:
OutputProfile(const String8 & name)167     explicit OutputProfile(const String8 &name) : IOProfile(name, AUDIO_PORT_ROLE_SOURCE) {}
168 };
169 
170 } // namespace android
171