• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android-base/stringprintf.h>
23 #include <audio_utils/string.h>
24 #include <media/AudioParameter.h>
25 #include <media/TypeConverter.h>
26 #include <AudioPolicyInterface.h>
27 #include "DeviceDescriptor.h"
28 #include "TypeConverter.h"
29 #include "HwModule.h"
30 
31 namespace android {
32 
DeviceDescriptor(audio_devices_t type)33 DeviceDescriptor::DeviceDescriptor(audio_devices_t type) :
34         DeviceDescriptor(type, "" /*tagName*/)
35 {
36 }
37 
DeviceDescriptor(audio_devices_t type,const std::string & tagName,const FormatVector & encodedFormats)38 DeviceDescriptor::DeviceDescriptor(audio_devices_t type,
39                                    const std::string &tagName,
40                                    const FormatVector &encodedFormats) :
41         DeviceDescriptor(type, tagName, "" /*address*/, encodedFormats)
42 {
43 }
44 
DeviceDescriptor(audio_devices_t type,const std::string & tagName,const std::string & address,const FormatVector & encodedFormats)45 DeviceDescriptor::DeviceDescriptor(audio_devices_t type,
46                                    const std::string &tagName,
47                                    const std::string &address,
48                                    const FormatVector &encodedFormats) :
49         DeviceDescriptor(AudioDeviceTypeAddr(type, address), tagName, encodedFormats)
50 {
51 }
52 
53 // Let DeviceDescriptorBase initialize the address since it handles specific cases like
54 // legacy remote submix where "0" is added as default address.
DeviceDescriptor(const AudioDeviceTypeAddr & deviceTypeAddr,const std::string & tagName,const FormatVector & encodedFormats)55 DeviceDescriptor::DeviceDescriptor(const AudioDeviceTypeAddr &deviceTypeAddr,
56                                    const std::string &tagName,
57                                    const FormatVector &encodedFormats) :
58         DeviceDescriptorBase(deviceTypeAddr, encodedFormats), mTagName(tagName),
59         mDeclaredAddress(DeviceDescriptorBase::address())
60 {
61     mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
62 }
63 
attach(const sp<HwModule> & module)64 void DeviceDescriptor::attach(const sp<HwModule>& module)
65 {
66     PolicyAudioPort::attach(module);
67     mId = getNextUniqueId();
68 }
69 
detach()70 void DeviceDescriptor::detach() {
71     mId = AUDIO_PORT_HANDLE_NONE;
72     PolicyAudioPort::detach();
73     // The device address may have been overwritten on device connection
74     setAddress(mDeclaredAddress);
75     // Device Port does not have a name unless provided by setDeviceConnectionState
76     setName("");
77 }
78 
79 template<typename T>
checkEqual(const T & f1,const T & f2)80 bool checkEqual(const T& f1, const T& f2)
81 {
82     std::set<typename T::value_type> s1(f1.begin(), f1.end());
83     std::set<typename T::value_type> s2(f2.begin(), f2.end());
84     return s1 == s2;
85 }
86 
equals(const sp<DeviceDescriptor> & other) const87 bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
88 {
89     // Devices are considered equal if they:
90     // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
91     // - have the same address
92     // - have the same encodingFormats (if device supports encoding)
93     if (other == 0) {
94         return false;
95     }
96 
97     return mDeviceTypeAddr.equals(other->mDeviceTypeAddr) &&
98            checkEqual(mEncodedFormats, other->mEncodedFormats);
99 }
100 
hasCurrentEncodedFormat() const101 bool DeviceDescriptor::hasCurrentEncodedFormat() const
102 {
103     if (!device_has_encoding_capability(type())) {
104         return true;
105     }
106     if (mEncodedFormats.empty()) {
107         return true;
108     }
109 
110     return (mCurrentEncodedFormat != AUDIO_FORMAT_DEFAULT);
111 }
112 
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)113 status_t DeviceDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
114                                                 audio_port_config *backupConfig)
115 {
116     struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
117     status_t status = NO_ERROR;
118 
119     toAudioPortConfig(&localBackupConfig);
120     if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
121         AudioPortConfig::applyAudioPortConfig(config, backupConfig);
122     }
123 
124     if (backupConfig != NULL) {
125         *backupConfig = localBackupConfig;
126     }
127     return status;
128 }
129 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const130 void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
131                                          const struct audio_port_config *srcConfig) const
132 {
133     DeviceDescriptorBase::toAudioPortConfig(dstConfig, srcConfig);
134     dstConfig->ext.device.hw_module = getModuleHandle();
135     if (mPreferredConfig.has_value()) {
136         if (mPreferredConfig->format != AUDIO_FORMAT_DEFAULT) {
137             dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
138             dstConfig->format = mPreferredConfig->format;
139         }
140         if (mPreferredConfig->sample_rate != 0) {
141             dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
142             dstConfig->sample_rate = mPreferredConfig->sample_rate;
143         }
144         if (mPreferredConfig->channel_mask != AUDIO_CHANNEL_NONE) {
145             dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
146             dstConfig->channel_mask = mPreferredConfig->channel_mask;
147         }
148     }
149 }
150 
toAudioPort(struct audio_port * port) const151 void DeviceDescriptor::toAudioPort(struct audio_port *port) const
152 {
153     ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceTypeAddr.mType);
154     toAudioPortInternal(port);
155 }
156 
toAudioPort(struct audio_port_v7 * port) const157 void DeviceDescriptor::toAudioPort(struct audio_port_v7 *port) const {
158     ALOGV("DeviceDescriptor::toAudioPort() v7 handle %d type %08x", mId, mDeviceTypeAddr.mType);
159     toAudioPortInternal(port);
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 
readFromParcelable(const media::AudioPortFw & parcelable)171 status_t DeviceDescriptor::readFromParcelable(const media::AudioPortFw& parcelable) {
172     RETURN_STATUS_IF_ERROR(DeviceDescriptorBase::readFromParcelable(parcelable));
173     mDeclaredAddress = DeviceDescriptorBase::address();
174     return OK;
175 }
176 
setEncapsulationInfoFromHal(AudioPolicyClientInterface * clientInterface)177 void DeviceDescriptor::setEncapsulationInfoFromHal(
178         AudioPolicyClientInterface *clientInterface) {
179     AudioParameter param(String8(mDeviceTypeAddr.getAddress()));
180     param.addInt(String8(AudioParameter::keyRouting), mDeviceTypeAddr.mType);
181     param.addKey(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES));
182     param.addKey(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES));
183     String8 reply = clientInterface->getParameters(AUDIO_IO_HANDLE_NONE, param.toString());
184     AudioParameter repliedParameters(reply);
185     int value;
186     if (repliedParameters.getInt(
187             String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES), value) == NO_ERROR) {
188         if (setEncapsulationModes(value) != NO_ERROR) {
189             ALOGE("Failed to set encapsulation mode(%d)", value);
190         }
191     }
192     if (repliedParameters.getInt(
193             String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES), value) == NO_ERROR) {
194         if (setEncapsulationMetadataTypes(value) != NO_ERROR) {
195             ALOGE("Failed to set encapsulation metadata types(%d)", value);
196         }
197     }
198 }
199 
setPreferredConfig(const audio_config_base_t * preferredConfig)200 void DeviceDescriptor::setPreferredConfig(const audio_config_base_t* preferredConfig) {
201     if (preferredConfig == nullptr) {
202         mPreferredConfig.reset();
203     } else {
204         mPreferredConfig = *preferredConfig;
205     }
206 }
207 
dump(String8 * dst,int spaces,bool verbose) const208 void DeviceDescriptor::dump(String8 *dst, int spaces, bool verbose) const
209 {
210     String8 extraInfo;
211     if (!mTagName.empty()) {
212         extraInfo.appendFormat("\"%s\"", mTagName.c_str());
213     }
214 
215     std::string descBaseDumpStr;
216     DeviceDescriptorBase::dump(&descBaseDumpStr, spaces, extraInfo.c_str(), verbose);
217     dst->append(descBaseDumpStr.c_str());
218 
219     if (mPreferredConfig.has_value()) {
220         dst->append(base::StringPrintf(
221                 "%*sPreferred Config: format=%#x, channelMask=%#x, sampleRate=%u\n",
222                 spaces, "", mPreferredConfig.value().format, mPreferredConfig.value().channel_mask,
223                 mPreferredConfig.value().sample_rate).c_str());
224     }
225 }
226 
227 
refreshTypes()228 void DeviceVector::refreshTypes()
229 {
230     mDeviceTypes.clear();
231     for (size_t i = 0; i < size(); i++) {
232         mDeviceTypes.insert(itemAt(i)->type());
233     }
234     ALOGV("DeviceVector::refreshTypes() mDeviceTypes %s", dumpDeviceTypes(mDeviceTypes).c_str());
235 }
236 
refreshAudioProfiles()237 void DeviceVector::refreshAudioProfiles() {
238     if (empty()) {
239         mSupportedProfiles.clear();
240         return;
241     }
242     mSupportedProfiles = itemAt(0)->getAudioProfiles();
243     for (size_t i = 1; i < size(); ++i) {
244         mSupportedProfiles = intersectAudioProfiles(
245                 mSupportedProfiles, itemAt(i)->getAudioProfiles());
246     }
247 }
248 
indexOf(const sp<DeviceDescriptor> & item) const249 ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
250 {
251     for (size_t i = 0; i < size(); i++) {
252         if (itemAt(i)->equals(item)) { // item may be null sp<>, i.e. AUDIO_DEVICE_NONE
253             return i;
254         }
255     }
256     return -1;
257 }
258 
add(const DeviceVector & devices)259 void DeviceVector::add(const DeviceVector &devices)
260 {
261     bool added = false;
262     for (const auto& device : devices) {
263         if (device && indexOf(device) < 0 && SortedVector::add(device) >= 0) {
264             added = true;
265         }
266     }
267     if (added) {
268         refreshTypes();
269         refreshAudioProfiles();
270     }
271 }
272 
add(const sp<DeviceDescriptor> & item)273 ssize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
274 {
275     if (!item) {
276         ALOGW("DeviceVector::%s() null device", __func__);
277         return -1;
278     }
279     ssize_t ret = indexOf(item);
280 
281     if (ret < 0) {
282         ret = SortedVector::add(item);
283         if (ret >= 0) {
284             refreshTypes();
285             refreshAudioProfiles();
286         }
287     } else {
288         ALOGW("DeviceVector::add device %08x already in", item->type());
289         ret = -1;
290     }
291     return ret;
292 }
293 
do_compare(const void * lhs,const void * rhs) const294 int DeviceVector::do_compare(const void* lhs, const void* rhs) const {
295     const auto ldevice = *reinterpret_cast<const sp<DeviceDescriptor>*>(lhs);
296     const auto rdevice = *reinterpret_cast<const sp<DeviceDescriptor>*>(rhs);
297     int ret = 0;
298 
299     // sort by type.
300     ret = compare_type(ldevice->type(), rdevice->type());
301     if (ret != 0)
302         return ret;
303     // for same type higher priority for latest device.
304     ret = compare_type(rdevice->getId(), ldevice->getId());
305     if (ret != 0)
306         return ret;
307     // fallback to default sort using pointer address
308     return SortedVector::do_compare(lhs, rhs);
309 }
310 
remove(const sp<DeviceDescriptor> & item)311 ssize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
312 {
313     ssize_t ret = indexOf(item);
314 
315     if (ret < 0) {
316         ALOGW("DeviceVector::remove device %08x not in", item->type());
317     } else {
318         ret = SortedVector::removeAt(ret);
319         if (ret >= 0) {
320             refreshTypes();
321             refreshAudioProfiles();
322         }
323     }
324     return ret;
325 }
326 
remove(const DeviceVector & devices)327 void DeviceVector::remove(const DeviceVector &devices)
328 {
329     for (const auto& device : devices) {
330         remove(device);
331     }
332 }
333 
getDevicesFromHwModule(audio_module_handle_t moduleHandle) const334 DeviceVector DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
335 {
336     DeviceVector devices;
337     for (const auto& device : *this) {
338         if (device->getModuleHandle() == moduleHandle) {
339             devices.add(device);
340         }
341     }
342     return devices;
343 }
344 
getDevice(audio_devices_t type,const String8 & address,audio_format_t format) const345 sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address,
346                                              audio_format_t format) const
347 {
348     sp<DeviceDescriptor> device;
349     for (size_t i = 0; i < size(); i++) {
350         if (itemAt(i)->type() == type) {
351             // If format is specified, match it and ignore address
352             // Otherwise if address is specified match it
353             // Otherwise always match
354             if (((address == "" || (itemAt(i)->address().compare(address.c_str()) == 0)) &&
355                  format == AUDIO_FORMAT_DEFAULT) ||
356                 (itemAt(i)->supportsFormat(format) && format != AUDIO_FORMAT_DEFAULT)) {
357                 device = itemAt(i);
358                 if (itemAt(i)->address().compare(address.c_str()) == 0) {
359                     break;
360                 }
361             }
362         }
363     }
364     ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
365             __func__, type, address.c_str(), device.get(), format);
366     return device;
367 }
368 
getDeviceFromId(audio_port_handle_t id) const369 sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
370 {
371     if (id != AUDIO_PORT_HANDLE_NONE) {
372         for (const auto& device : *this) {
373             if (device->getId() == id) {
374                 return device;
375             }
376         }
377     }
378     return nullptr;
379 }
380 
getDevicesFromTypes(const DeviceTypeSet & types) const381 DeviceVector DeviceVector::getDevicesFromTypes(const DeviceTypeSet& types) const
382 {
383     DeviceVector devices;
384     if (types.empty()) {
385         return devices;
386     }
387     for (size_t i = 0; i < size(); i++) {
388         if (types.count(itemAt(i)->type()) != 0) {
389             devices.add(itemAt(i));
390             ALOGV("DeviceVector::%s() for type %08x found %p",
391                     __func__, itemAt(i)->type(), itemAt(i).get());
392         }
393     }
394     return devices;
395 }
396 
getDeviceFromTagName(const std::string & tagName) const397 sp<DeviceDescriptor> DeviceVector::getDeviceFromTagName(const std::string &tagName) const
398 {
399     for (const auto& device : *this) {
400         if (device->getTagName() == tagName) {
401             return device;
402         }
403     }
404     return nullptr;
405 }
406 
getFirstDevicesFromTypes(std::vector<audio_devices_t> orderedTypes) const407 DeviceVector DeviceVector::getFirstDevicesFromTypes(
408         std::vector<audio_devices_t> orderedTypes) const
409 {
410     DeviceVector devices;
411     for (auto deviceType : orderedTypes) {
412         if (!(devices = getDevicesFromType(deviceType)).isEmpty()) {
413             break;
414         }
415     }
416     return devices;
417 }
418 
getFirstExistingDevice(std::vector<audio_devices_t> orderedTypes) const419 sp<DeviceDescriptor> DeviceVector::getFirstExistingDevice(
420         std::vector<audio_devices_t> orderedTypes) const {
421     sp<DeviceDescriptor> device;
422     for (auto deviceType : orderedTypes) {
423         if ((device = getDevice(deviceType, String8(""), AUDIO_FORMAT_DEFAULT)) != nullptr) {
424             break;
425         }
426     }
427     return device;
428 }
429 
getDeviceForOpening() const430 sp<DeviceDescriptor> DeviceVector::getDeviceForOpening() const
431 {
432     if (isEmpty()) {
433         // Return nullptr if this collection is empty.
434         return nullptr;
435     } else if (areAllOfSameDeviceType(types(), audio_call_is_input_device)) {
436         // For input case, return the first one when there is only one device.
437         return size() > 1 ? nullptr : *begin();
438     } else if (areAllOfSameDeviceType(types(), audio_is_output_device)) {
439         // For output case, return the device descriptor according to apm strategy.
440         audio_devices_t deviceType = apm_extract_one_audio_device(types());
441         return deviceType == AUDIO_DEVICE_NONE ? nullptr :
442                 getDevice(deviceType, String8(""), AUDIO_FORMAT_DEFAULT);
443     }
444     // Return null pointer if the devices are not all input/output device.
445     return nullptr;
446 }
447 
getDeviceFromDeviceTypeAddr(const AudioDeviceTypeAddr & deviceTypeAddr) const448 sp<DeviceDescriptor> DeviceVector::getDeviceFromDeviceTypeAddr(
449             const AudioDeviceTypeAddr& deviceTypeAddr) const {
450     return getDevice(deviceTypeAddr.mType, String8(deviceTypeAddr.getAddress()),
451             AUDIO_FORMAT_DEFAULT);
452 }
453 
getDevicesFromDeviceTypeAddrVec(const AudioDeviceTypeAddrVector & deviceTypeAddrVector) const454 DeviceVector DeviceVector::getDevicesFromDeviceTypeAddrVec(
455         const AudioDeviceTypeAddrVector& deviceTypeAddrVector) const {
456     DeviceVector devices;
457     for (const auto& deviceTypeAddr : deviceTypeAddrVector) {
458         sp<DeviceDescriptor> device = getDeviceFromDeviceTypeAddr(deviceTypeAddr);
459         if (device != nullptr) {
460             devices.add(device);
461         }
462     }
463     return devices;
464 }
465 
toTypeAddrVector() const466 AudioDeviceTypeAddrVector DeviceVector::toTypeAddrVector() const {
467     AudioDeviceTypeAddrVector result;
468     for (const auto& device : *this) {
469         result.push_back(AudioDeviceTypeAddr(device->type(), device->address()));
470     }
471     return result;
472 }
473 
replaceDevicesByType(audio_devices_t typeToRemove,const DeviceVector & devicesToAdd)474 void DeviceVector::replaceDevicesByType(
475         audio_devices_t typeToRemove, const DeviceVector &devicesToAdd) {
476     DeviceVector devicesToRemove = getDevicesFromType(typeToRemove);
477     if (!devicesToRemove.isEmpty() && !devicesToAdd.isEmpty()) {
478         remove(devicesToRemove);
479         add(devicesToAdd);
480     }
481 }
482 
dump(String8 * dst,const String8 & tag,int spaces,bool verbose) const483 void DeviceVector::dump(String8 *dst, const String8 &tag, int spaces, bool verbose) const
484 {
485     if (isEmpty()) {
486         return;
487     }
488     dst->appendFormat("%*s%s devices (%zu):\n", spaces, "", tag.c_str(), size());
489     for (size_t i = 0; i < size(); i++) {
490         const std::string prefix = base::StringPrintf("%*s %zu. ", spaces, "", i + 1);
491         dst->appendFormat("%s", prefix.c_str());
492         itemAt(i)->dump(dst, prefix.size(), verbose);
493     }
494 }
495 
toString(bool includeSensitiveInfo) const496 std::string DeviceVector::toString(bool includeSensitiveInfo) const
497 {
498     if (isEmpty()) {
499         return {"AUDIO_DEVICE_NONE"};
500     }
501     std::string result = {"{"};
502     for (const auto &device : *this) {
503         if (device != *begin()) {
504            result += ";";
505         }
506         result += device->toString(includeSensitiveInfo);
507     }
508     return result + "}";
509 }
510 
filter(const DeviceVector & devices) const511 DeviceVector DeviceVector::filter(const DeviceVector &devices) const
512 {
513     DeviceVector filteredDevices;
514     for (const auto &device : *this) {
515         if (devices.contains(device)) {
516             filteredDevices.add(device);
517         }
518     }
519     return filteredDevices;
520 }
521 
containsAtLeastOne(const DeviceVector & devices) const522 bool DeviceVector::containsAtLeastOne(const DeviceVector &devices) const
523 {
524     return !filter(devices).isEmpty();
525 }
526 
containsAllDevices(const DeviceVector & devices) const527 bool DeviceVector::containsAllDevices(const DeviceVector &devices) const
528 {
529     return filter(devices).size() == devices.size();
530 }
531 
filterForEngine() const532 DeviceVector DeviceVector::filterForEngine() const
533 {
534     DeviceVector filteredDevices;
535     for (const auto &device : *this) {
536         if (audio_is_remote_submix_device(device->type()) && device->address() != "0") {
537             continue;
538         }
539         filteredDevices.add(device);
540     }
541     return filteredDevices;
542 }
543 
544 } // namespace android
545