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 #define LOG_TAG "APM::IOProfile"
18 //#define LOG_NDEBUG 0
19 
20 #include "IOProfile.h"
21 #include "HwModule.h"
22 #include "AudioGain.h"
23 
24 namespace android {
25 
IOProfile(const String8 & name,audio_port_role_t role)26 IOProfile::IOProfile(const String8& name, audio_port_role_t role)
27     : AudioPort(name, AUDIO_PORT_TYPE_MIX, role)
28 {
29 }
30 
~IOProfile()31 IOProfile::~IOProfile()
32 {
33 }
34 
35 // checks if the IO profile is compatible with specified parameters.
36 // Sampling rate, format and channel mask must be specified in order to
37 // get a valid a match
isCompatibleProfile(audio_devices_t device,String8 address,uint32_t samplingRate,uint32_t * updatedSamplingRate,audio_format_t format,audio_format_t * updatedFormat,audio_channel_mask_t channelMask,audio_channel_mask_t * updatedChannelMask,uint32_t flags) const38 bool IOProfile::isCompatibleProfile(audio_devices_t device,
39                                     String8 address,
40                                     uint32_t samplingRate,
41                                     uint32_t *updatedSamplingRate,
42                                     audio_format_t format,
43                                     audio_format_t *updatedFormat,
44                                     audio_channel_mask_t channelMask,
45                                     audio_channel_mask_t *updatedChannelMask,
46                                     uint32_t flags) const
47 {
48     const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE;
49     const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
50     ALOG_ASSERT(isPlaybackThread != isRecordThread);
51 
52 
53     if (device != AUDIO_DEVICE_NONE) {
54         // just check types if multiple devices are selected
55         if (popcount(device & ~AUDIO_DEVICE_BIT_IN) > 1) {
56             if ((mSupportedDevices.types() & device) != device) {
57                 return false;
58             }
59         } else if (mSupportedDevices.getDevice(device, address) == 0) {
60             return false;
61         }
62     }
63 
64     if (samplingRate == 0) {
65          return false;
66     }
67     uint32_t myUpdatedSamplingRate = samplingRate;
68     if (isPlaybackThread && checkExactSamplingRate(samplingRate) != NO_ERROR) {
69          return false;
70     }
71     if (isRecordThread && checkCompatibleSamplingRate(samplingRate, &myUpdatedSamplingRate) !=
72             NO_ERROR) {
73          return false;
74     }
75 
76     if (!audio_is_valid_format(format)) {
77         return false;
78     }
79     if (isPlaybackThread && checkExactFormat(format) != NO_ERROR) {
80         return false;
81     }
82     audio_format_t myUpdatedFormat = format;
83     if (isRecordThread && checkCompatibleFormat(format, &myUpdatedFormat) != NO_ERROR) {
84         return false;
85     }
86 
87     if (isPlaybackThread && (!audio_is_output_channel(channelMask) ||
88             checkExactChannelMask(channelMask) != NO_ERROR)) {
89         return false;
90     }
91     audio_channel_mask_t myUpdatedChannelMask = channelMask;
92     if (isRecordThread && (!audio_is_input_channel(channelMask) ||
93             checkCompatibleChannelMask(channelMask, &myUpdatedChannelMask) != NO_ERROR)) {
94         return false;
95     }
96 
97     if (isPlaybackThread && (mFlags & flags) != flags) {
98         return false;
99     }
100     // The only input flag that is allowed to be different is the fast flag.
101     // An existing fast stream is compatible with a normal track request.
102     // An existing normal stream is compatible with a fast track request,
103     // but the fast request will be denied by AudioFlinger and converted to normal track.
104     if (isRecordThread && ((mFlags ^ flags) &
105             ~AUDIO_INPUT_FLAG_FAST)) {
106         return false;
107     }
108 
109     if (updatedSamplingRate != NULL) {
110         *updatedSamplingRate = myUpdatedSamplingRate;
111     }
112     if (updatedFormat != NULL) {
113         *updatedFormat = myUpdatedFormat;
114     }
115     if (updatedChannelMask != NULL) {
116         *updatedChannelMask = myUpdatedChannelMask;
117     }
118     return true;
119 }
120 
dump(int fd)121 void IOProfile::dump(int fd)
122 {
123     const size_t SIZE = 256;
124     char buffer[SIZE];
125     String8 result;
126 
127     AudioPort::dump(fd, 4);
128 
129     snprintf(buffer, SIZE, "    - flags: 0x%04x\n", mFlags);
130     result.append(buffer);
131     snprintf(buffer, SIZE, "    - devices:\n");
132     result.append(buffer);
133     write(fd, result.string(), result.size());
134     for (size_t i = 0; i < mSupportedDevices.size(); i++) {
135         mSupportedDevices[i]->dump(fd, 6, i);
136     }
137 }
138 
log()139 void IOProfile::log()
140 {
141     const size_t SIZE = 256;
142     char buffer[SIZE];
143     String8 result;
144 
145     ALOGV("    - sampling rates: ");
146     for (size_t i = 0; i < mSamplingRates.size(); i++) {
147         ALOGV("  %d", mSamplingRates[i]);
148     }
149 
150     ALOGV("    - channel masks: ");
151     for (size_t i = 0; i < mChannelMasks.size(); i++) {
152         ALOGV("  0x%04x", mChannelMasks[i]);
153     }
154 
155     ALOGV("    - formats: ");
156     for (size_t i = 0; i < mFormats.size(); i++) {
157         ALOGV("  0x%08x", mFormats[i]);
158     }
159 
160     ALOGV("    - devices: 0x%04x\n", mSupportedDevices.types());
161     ALOGV("    - flags: 0x%04x\n", mFlags);
162 }
163 
164 }; // namespace android
165