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::Devices"
18 //#define LOG_NDEBUG 0
19 
20 #include <set>
21 
22 #include <AudioPolicyInterface.h>
23 #include <audio_utils/string.h>
24 #include <media/AudioParameter.h>
25 #include <media/TypeConverter.h>
26 #include "DeviceDescriptor.h"
27 #include "TypeConverter.h"
28 #include "HwModule.h"
29 
30 namespace android {
31 
DeviceDescriptor(audio_devices_t type)32 DeviceDescriptor::DeviceDescriptor(audio_devices_t type) :
33         DeviceDescriptor(type, "" /*tagName*/)
34 {
35 }
36 
DeviceDescriptor(audio_devices_t type,const std::string & tagName,const FormatVector & encodedFormats)37 DeviceDescriptor::DeviceDescriptor(audio_devices_t type,
38                                    const std::string &tagName,
39                                    const FormatVector &encodedFormats) :
40         DeviceDescriptor(type, tagName, "" /*address*/, encodedFormats)
41 {
42 }
43 
DeviceDescriptor(audio_devices_t type,const std::string & tagName,const std::string & address,const FormatVector & encodedFormats)44 DeviceDescriptor::DeviceDescriptor(audio_devices_t type,
45                                    const std::string &tagName,
46                                    const std::string &address,
47                                    const FormatVector &encodedFormats) :
48         DeviceDescriptor(AudioDeviceTypeAddr(type, address), tagName, encodedFormats)
49 {
50 }
51 
DeviceDescriptor(const AudioDeviceTypeAddr & deviceTypeAddr,const std::string & tagName,const FormatVector & encodedFormats)52 DeviceDescriptor::DeviceDescriptor(const AudioDeviceTypeAddr &deviceTypeAddr,
53                                    const std::string &tagName,
54                                    const FormatVector &encodedFormats) :
55         DeviceDescriptorBase(deviceTypeAddr), mTagName(tagName), mEncodedFormats(encodedFormats)
56 {
57     mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
58     /* If framework runs against a pre 5.0 Audio HAL, encoded formats are absent from the config.
59      * FIXME: APM should know the version of the HAL and don't add the formats for V5.0.
60      * For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
61      * something like 'encodedFormats="AUDIO_FORMAT_PCM_16_BIT"' on the HDMI devicePort.
62      */
63     if (mDeviceTypeAddr.mType == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.empty()) {
64         mEncodedFormats.push_back(AUDIO_FORMAT_AC3);
65         mEncodedFormats.push_back(AUDIO_FORMAT_IEC61937);
66     }
67 }
68 
attach(const sp<HwModule> & module)69 void DeviceDescriptor::attach(const sp<HwModule>& module)
70 {
71     PolicyAudioPort::attach(module);
72     mId = getNextUniqueId();
73 }
74 
detach()75 void DeviceDescriptor::detach() {
76     mId = AUDIO_PORT_HANDLE_NONE;
77     PolicyAudioPort::detach();
78 }
79 
80 template<typename T>
checkEqual(const T & f1,const T & f2)81 bool checkEqual(const T& f1, const T& f2)
82 {
83     std::set<typename T::value_type> s1(f1.begin(), f1.end());
84     std::set<typename T::value_type> s2(f2.begin(), f2.end());
85     return s1 == s2;
86 }
87 
equals(const sp<DeviceDescriptor> & other) const88 bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
89 {
90     // Devices are considered equal if they:
91     // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
92     // - have the same address
93     // - have the same encodingFormats (if device supports encoding)
94     if (other == 0) {
95         return false;
96     }
97 
98     return mDeviceTypeAddr.equals(other->mDeviceTypeAddr) &&
99            checkEqual(mEncodedFormats, other->mEncodedFormats);
100 }
101 
hasCurrentEncodedFormat() const102 bool DeviceDescriptor::hasCurrentEncodedFormat() const
103 {
104     if (!device_has_encoding_capability(type())) {
105         return true;
106     }
107     if (mEncodedFormats.empty()) {
108         return true;
109     }
110 
111     return (mCurrentEncodedFormat != AUDIO_FORMAT_DEFAULT);
112 }
113 
supportsFormat(audio_format_t format)114 bool DeviceDescriptor::supportsFormat(audio_format_t format)
115 {
116     if (mEncodedFormats.empty()) {
117         return true;
118     }
119 
120     for (const auto& devFormat : mEncodedFormats) {
121         if (devFormat == format) {
122             return true;
123         }
124     }
125     return false;
126 }
127 
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)128 status_t DeviceDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
129                                                 audio_port_config *backupConfig)
130 {
131     struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
132     status_t status = NO_ERROR;
133 
134     toAudioPortConfig(&localBackupConfig);
135     if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
136         AudioPortConfig::applyAudioPortConfig(config, backupConfig);
137         applyPolicyAudioPortConfig(config);
138     }
139 
140     if (backupConfig != NULL) {
141         *backupConfig = localBackupConfig;
142     }
143     return status;
144 }
145 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const146 void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
147                                          const struct audio_port_config *srcConfig) const
148 {
149     DeviceDescriptorBase::toAudioPortConfig(dstConfig, srcConfig);
150     toPolicyAudioPortConfig(dstConfig, srcConfig);
151 
152     dstConfig->ext.device.hw_module = getModuleHandle();
153 }
154 
toAudioPort(struct audio_port * port) const155 void DeviceDescriptor::toAudioPort(struct audio_port *port) const
156 {
157     ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceTypeAddr.mType);
158     DeviceDescriptorBase::toAudioPort(port);
159     port->ext.device.hw_module = getModuleHandle();
160 }
161 
importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort> & policyPort,bool force)162 void DeviceDescriptor::importAudioPortAndPickAudioProfile(
163         const sp<PolicyAudioPort>& policyPort, bool force) {
164     if (!force && !policyPort->asAudioPort()->hasDynamicAudioProfile()) {
165         return;
166     }
167     AudioPort::importAudioPort(policyPort->asAudioPort());
168     policyPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
169 }
170 
setEncapsulationInfoFromHal(AudioPolicyClientInterface * clientInterface)171 void DeviceDescriptor::setEncapsulationInfoFromHal(
172         AudioPolicyClientInterface *clientInterface) {
173     AudioParameter param(String8(mDeviceTypeAddr.getAddress()));
174     param.addInt(String8(AudioParameter::keyRouting), mDeviceTypeAddr.mType);
175     param.addKey(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES));
176     param.addKey(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES));
177     String8 reply = clientInterface->getParameters(AUDIO_IO_HANDLE_NONE, param.toString());
178     AudioParameter repliedParameters(reply);
179     int value;
180     if (repliedParameters.getInt(
181             String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES), value) == NO_ERROR) {
182         if (setEncapsulationModes(value) != NO_ERROR) {
183             ALOGE("Failed to set encapsulation mode(%d)", value);
184         }
185     }
186     if (repliedParameters.getInt(
187             String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES), value) == NO_ERROR) {
188         if (setEncapsulationMetadataTypes(value) != NO_ERROR) {
189             ALOGE("Failed to set encapsulation metadata types(%d)", value);
190         }
191     }
192 }
193 
dump(String8 * dst,int spaces,int index,bool verbose) const194 void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
195 {
196     String8 extraInfo;
197     if (!mTagName.empty()) {
198         extraInfo.appendFormat("%*s- tag name: %s\n", spaces, "", mTagName.c_str());
199     }
200 
201     std::string descBaseDumpStr;
202     DeviceDescriptorBase::dump(&descBaseDumpStr, spaces, index, extraInfo.string(), verbose);
203     dst->append(descBaseDumpStr.c_str());
204 }
205 
206 
refreshTypes()207 void DeviceVector::refreshTypes()
208 {
209     mDeviceTypes.clear();
210     for (size_t i = 0; i < size(); i++) {
211         mDeviceTypes.insert(itemAt(i)->type());
212     }
213     ALOGV("DeviceVector::refreshTypes() mDeviceTypes %s", dumpDeviceTypes(mDeviceTypes).c_str());
214 }
215 
indexOf(const sp<DeviceDescriptor> & item) const216 ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
217 {
218     for (size_t i = 0; i < size(); i++) {
219         if (itemAt(i)->equals(item)) { // item may be null sp<>, i.e. AUDIO_DEVICE_NONE
220             return i;
221         }
222     }
223     return -1;
224 }
225 
add(const DeviceVector & devices)226 void DeviceVector::add(const DeviceVector &devices)
227 {
228     bool added = false;
229     for (const auto& device : devices) {
230         if (indexOf(device) < 0 && SortedVector::add(device) >= 0) {
231             added = true;
232         }
233     }
234     if (added) {
235         refreshTypes();
236     }
237 }
238 
add(const sp<DeviceDescriptor> & item)239 ssize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
240 {
241     ssize_t ret = indexOf(item);
242 
243     if (ret < 0) {
244         ret = SortedVector::add(item);
245         if (ret >= 0) {
246             refreshTypes();
247         }
248     } else {
249         ALOGW("DeviceVector::add device %08x already in", item->type());
250         ret = -1;
251     }
252     return ret;
253 }
254 
remove(const sp<DeviceDescriptor> & item)255 ssize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
256 {
257     ssize_t ret = indexOf(item);
258 
259     if (ret < 0) {
260         ALOGW("DeviceVector::remove device %08x not in", item->type());
261     } else {
262         ret = SortedVector::removeAt(ret);
263         if (ret >= 0) {
264             refreshTypes();
265         }
266     }
267     return ret;
268 }
269 
remove(const DeviceVector & devices)270 void DeviceVector::remove(const DeviceVector &devices)
271 {
272     for (const auto& device : devices) {
273         remove(device);
274     }
275 }
276 
getDevicesFromHwModule(audio_module_handle_t moduleHandle) const277 DeviceVector DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
278 {
279     DeviceVector devices;
280     for (const auto& device : *this) {
281         if (device->getModuleHandle() == moduleHandle) {
282             devices.add(device);
283         }
284     }
285     return devices;
286 }
287 
getDevice(audio_devices_t type,const String8 & address,audio_format_t format) const288 sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address,
289                                              audio_format_t format) const
290 {
291     sp<DeviceDescriptor> device;
292     for (size_t i = 0; i < size(); i++) {
293         if (itemAt(i)->type() == type) {
294             // If format is specified, match it and ignore address
295             // Otherwise if address is specified match it
296             // Otherwise always match
297             if (((address == "" || (itemAt(i)->address().compare(address.c_str()) == 0)) &&
298                  format == AUDIO_FORMAT_DEFAULT) ||
299                 (itemAt(i)->supportsFormat(format) && format != AUDIO_FORMAT_DEFAULT)) {
300                 device = itemAt(i);
301                 if (itemAt(i)->address().compare(address.c_str()) == 0) {
302                     break;
303                 }
304             }
305         }
306     }
307     ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
308             __func__, type, address.string(), device.get(), format);
309     return device;
310 }
311 
getDeviceFromId(audio_port_handle_t id) const312 sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
313 {
314     if (id != AUDIO_PORT_HANDLE_NONE) {
315         for (const auto& device : *this) {
316             if (device->getId() == id) {
317                 return device;
318             }
319         }
320     }
321     return nullptr;
322 }
323 
getDevicesFromTypes(const DeviceTypeSet & types) const324 DeviceVector DeviceVector::getDevicesFromTypes(const DeviceTypeSet& types) const
325 {
326     DeviceVector devices;
327     if (types.empty()) {
328         return devices;
329     }
330     for (size_t i = 0; i < size(); i++) {
331         if (types.count(itemAt(i)->type()) != 0) {
332             devices.add(itemAt(i));
333             ALOGV("DeviceVector::%s() for type %08x found %p",
334                     __func__, itemAt(i)->type(), itemAt(i).get());
335         }
336     }
337     return devices;
338 }
339 
getDeviceFromTagName(const std::string & tagName) const340 sp<DeviceDescriptor> DeviceVector::getDeviceFromTagName(const std::string &tagName) const
341 {
342     for (const auto& device : *this) {
343         if (device->getTagName() == tagName) {
344             return device;
345         }
346     }
347     return nullptr;
348 }
349 
getFirstDevicesFromTypes(std::vector<audio_devices_t> orderedTypes) const350 DeviceVector DeviceVector::getFirstDevicesFromTypes(
351         std::vector<audio_devices_t> orderedTypes) const
352 {
353     DeviceVector devices;
354     for (auto deviceType : orderedTypes) {
355         if (!(devices = getDevicesFromType(deviceType)).isEmpty()) {
356             break;
357         }
358     }
359     return devices;
360 }
361 
getFirstExistingDevice(std::vector<audio_devices_t> orderedTypes) const362 sp<DeviceDescriptor> DeviceVector::getFirstExistingDevice(
363         std::vector<audio_devices_t> orderedTypes) const {
364     sp<DeviceDescriptor> device;
365     for (auto deviceType : orderedTypes) {
366         if ((device = getDevice(deviceType, String8(""), AUDIO_FORMAT_DEFAULT)) != nullptr) {
367             break;
368         }
369     }
370     return device;
371 }
372 
getDeviceForOpening() const373 sp<DeviceDescriptor> DeviceVector::getDeviceForOpening() const
374 {
375     if (isEmpty()) {
376         // Return nullptr if this collection is empty.
377         return nullptr;
378     } else if (areAllOfSameDeviceType(types(), audio_is_input_device)) {
379         // For input case, return the first one when there is only one device.
380         return size() > 1 ? nullptr : *begin();
381     } else if (areAllOfSameDeviceType(types(), audio_is_output_device)) {
382         // For output case, return the device descriptor according to apm strategy.
383         audio_devices_t deviceType = apm_extract_one_audio_device(types());
384         return deviceType == AUDIO_DEVICE_NONE ? nullptr :
385                 getDevice(deviceType, String8(""), AUDIO_FORMAT_DEFAULT);
386     }
387     // Return null pointer if the devices are not all input/output device.
388     return nullptr;
389 }
390 
replaceDevicesByType(audio_devices_t typeToRemove,const DeviceVector & devicesToAdd)391 void DeviceVector::replaceDevicesByType(
392         audio_devices_t typeToRemove, const DeviceVector &devicesToAdd) {
393     DeviceVector devicesToRemove = getDevicesFromType(typeToRemove);
394     if (!devicesToRemove.isEmpty() && !devicesToAdd.isEmpty()) {
395         remove(devicesToRemove);
396         add(devicesToAdd);
397     }
398 }
399 
dump(String8 * dst,const String8 & tag,int spaces,bool verbose) const400 void DeviceVector::dump(String8 *dst, const String8 &tag, int spaces, bool verbose) const
401 {
402     if (isEmpty()) {
403         return;
404     }
405     dst->appendFormat("%*s- %s devices:\n", spaces, "", tag.string());
406     for (size_t i = 0; i < size(); i++) {
407         itemAt(i)->dump(dst, spaces + 2, i, verbose);
408     }
409 }
410 
toString() const411 std::string DeviceVector::toString() const
412 {
413     if (isEmpty()) {
414         return {"AUDIO_DEVICE_NONE"};
415     }
416     std::string result = {"{"};
417     for (const auto &device : *this) {
418         if (device != *begin()) {
419            result += ";";
420         }
421         result += device->toString();
422     }
423     return result + "}";
424 }
425 
filter(const DeviceVector & devices) const426 DeviceVector DeviceVector::filter(const DeviceVector &devices) const
427 {
428     DeviceVector filteredDevices;
429     for (const auto &device : *this) {
430         if (devices.contains(device)) {
431             filteredDevices.add(device);
432         }
433     }
434     return filteredDevices;
435 }
436 
containsAtLeastOne(const DeviceVector & devices) const437 bool DeviceVector::containsAtLeastOne(const DeviceVector &devices) const
438 {
439     return !filter(devices).isEmpty();
440 }
441 
containsAllDevices(const DeviceVector & devices) const442 bool DeviceVector::containsAllDevices(const DeviceVector &devices) const
443 {
444     return filter(devices).size() == devices.size();
445 }
446 
filterForEngine() const447 DeviceVector DeviceVector::filterForEngine() const
448 {
449     DeviceVector filteredDevices;
450     for (const auto &device : *this) {
451         if (audio_is_remote_submix_device(device->type()) && device->address() != "0") {
452             continue;
453         }
454         filteredDevices.add(device);
455     }
456     return filteredDevices;
457 }
458 
459 } // namespace android
460