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::AudioOutputDescriptor"
18 //#define LOG_NDEBUG 0
19 
20 #include <android-base/stringprintf.h>
21 
22 #include <AudioPolicyInterface.h>
23 #include "AudioOutputDescriptor.h"
24 #include "AudioPolicyMix.h"
25 #include <com_android_media_audio.h>
26 #include "IOProfile.h"
27 #include "Volume.h"
28 #include "HwModule.h"
29 #include "TypeConverter.h"
30 #include "policy.h"
31 #include <com_android_media_audioserver.h>
32 #include <media/AudioGain.h>
33 #include <media/AudioParameter.h>
34 #include <media/AudioPolicy.h>
35 
36 // A device mask for all audio output devices that are considered "remote" when evaluating
37 // active output devices in isStreamActiveRemotely()
38 
39 namespace audioserver_flags = com::android::media::audioserver;
40 
41 namespace android {
42 
getAllOutRemoteDevices()43 static const DeviceTypeSet& getAllOutRemoteDevices() {
44     static const DeviceTypeSet allOutRemoteDevices = {AUDIO_DEVICE_OUT_REMOTE_SUBMIX};
45     return allOutRemoteDevices;
46 }
47 
AudioOutputDescriptor(const sp<PolicyAudioPort> & policyAudioPort,AudioPolicyClientInterface * clientInterface)48 AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
49                                              AudioPolicyClientInterface *clientInterface)
50     : mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
51 {
52     if (mPolicyAudioPort.get() != nullptr) {
53         mPolicyAudioPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
54         if (mPolicyAudioPort->asAudioPort()->getGains().size() > 0) {
55             mPolicyAudioPort->asAudioPort()->getGains()[0]->getDefaultConfig(&mGain);
56         }
57     }
58 }
59 
getConfig() const60 audio_config_base_t AudioOutputDescriptor::getConfig() const
61 {
62     const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
63             .format = mFormat };
64     return config;
65 }
66 
getModuleHandle() const67 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
68 {
69     return mPolicyAudioPort.get() != nullptr ?
70             mPolicyAudioPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
71 }
72 
getPatchHandle() const73 audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
74 {
75     return mPatchHandle;
76 }
77 
setPatchHandle(audio_patch_handle_t handle)78 void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
79 {
80     mPatchHandle = handle;
81 }
82 
sharesHwModuleWith(const sp<AudioOutputDescriptor> & outputDesc)83 bool AudioOutputDescriptor::sharesHwModuleWith(
84         const sp<AudioOutputDescriptor>& outputDesc)
85 {
86     return hasSameHwModuleAs(outputDesc);
87 }
88 
setStopTime(const sp<TrackClientDescriptor> & client,nsecs_t sysTime)89 void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
90 {
91     mVolumeActivities[client->volumeSource()].setStopTime(sysTime);
92     mRoutingActivities[client->strategy()].setStopTime(sysTime);
93 }
94 
setClientActive(const sp<TrackClientDescriptor> & client,bool active)95 void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
96 {
97     auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client);
98     if (active == (clientIter != end(mActiveClients))) {
99         ALOGW("%s(%s): ignored active: %d, current stream count %d", __func__,
100               client->toShortString().c_str(), active,
101               mRoutingActivities.at(client->strategy()).getActivityCount());
102         return;
103     }
104     if (active) {
105         mActiveClients.push_back(client);
106     } else {
107         mActiveClients.erase(clientIter);
108     }
109     const int delta = active ? 1 : -1;
110     // If ps is unknown, it is time to track it!
111     mRoutingActivities[client->strategy()].changeActivityCount(delta);
112     mVolumeActivities[client->volumeSource()].changeActivityCount(delta);
113 
114     // Handle non-client-specific activity ref count
115     int32_t oldGlobalActiveCount = mGlobalActiveCount;
116     if (!active && mGlobalActiveCount < 1) {
117         ALOGW("%s(%s): invalid deactivation with globalRefCount %d",
118               __func__, client->toShortString().c_str(), mGlobalActiveCount);
119         mGlobalActiveCount = 1;
120     }
121     mGlobalActiveCount += delta;
122 
123     sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
124     if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
125         if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) {
126             mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
127                 mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE);
128         }
129     }
130     client->setActive(active);
131 }
132 
isClientActive(const sp<TrackClientDescriptor> & client)133 bool AudioOutputDescriptor::isClientActive(const sp<TrackClientDescriptor>& client)
134 {
135     return client != nullptr &&
136             std::find(begin(mActiveClients), end(mActiveClients), client) != end(mActiveClients);
137 }
138 
isActive(VolumeSource vs,uint32_t inPastMs,nsecs_t sysTime) const139 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
140 {
141     return (vs == VOLUME_SOURCE_NONE) ?
142                 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
143                 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
144 }
145 
isActive(uint32_t inPastMs) const146 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
147 {
148     nsecs_t sysTime = 0;
149     if (inPastMs != 0) {
150         sysTime = systemTime();
151     }
152     for (const auto &iter : mVolumeActivities) {
153         if (iter.second.isActive(inPastMs, sysTime)) {
154             return true;
155         }
156     }
157     return false;
158 }
159 
isFixedVolume(const DeviceTypeSet & deviceTypes __unused)160 bool AudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes __unused)
161 {
162     return false;
163 }
164 
setVolume(float volumeDb,bool mutedByGroup,VolumeSource volumeSource,const StreamTypeVector &,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force,bool isVoiceVolSrc)165 bool AudioOutputDescriptor::setVolume(float volumeDb, bool mutedByGroup,
166                                       VolumeSource volumeSource,
167                                       const StreamTypeVector &/*streams*/,
168                                       const DeviceTypeSet& deviceTypes,
169                                       uint32_t delayMs,
170                                       bool force,
171                                       bool isVoiceVolSrc)
172 {
173     if (!supportedDevices().containsDeviceAmongTypes(deviceTypes)) {
174         ALOGV("%s output ID %d unsupported device %s",
175                 __func__, getId(), toString(deviceTypes).c_str());
176         return false;
177     }
178     // We actually change the volume if:
179     // - the float value returned by computeVolume() changed
180     // - the muted state changed
181     // - the force flag is set
182     const bool mutedChanged =
183             com_android_media_audio_ring_my_car() && (isMutedByGroup(volumeSource) != mutedByGroup);
184     if (volumeDb != getCurVolume(volumeSource) || mutedChanged  || force) {
185         ALOGV("%s for volumeSrc %d, volume %f, mutedByGroup %d,  delay %d", __func__, volumeSource,
186               volumeDb, mutedByGroup, delayMs);
187         setCurVolume(volumeSource, volumeDb, mutedByGroup, isVoiceVolSrc);
188         return true;
189     }
190     return false;
191 }
192 
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)193 status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
194                                                      audio_port_config *backupConfig)
195 {
196     struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
197     status_t status = NO_ERROR;
198 
199     toAudioPortConfig(&localBackupConfig);
200     if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
201         AudioPortConfig::applyAudioPortConfig(config, backupConfig);
202     }
203 
204     if (backupConfig != NULL) {
205         *backupConfig = localBackupConfig;
206     }
207     return status;
208 }
209 
210 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const211 void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
212                                               const struct audio_port_config *srcConfig) const
213 {
214     dstConfig->config_mask = AUDIO_PORT_CONFIG_ALL;
215     if (srcConfig != NULL) {
216         dstConfig->config_mask |= srcConfig->config_mask;
217     }
218     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
219 
220     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
221     dstConfig->type = AUDIO_PORT_TYPE_MIX;
222     dstConfig->ext.mix.hw_module = getModuleHandle();
223     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
224 }
225 
toAudioPort(struct audio_port_v7 * port) const226 void AudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
227 {
228     // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
229     mPolicyAudioPort->asAudioPort()->toAudioPort(port);
230     port->id = mId;
231     port->ext.mix.hw_module = getModuleHandle();
232 }
233 
clientsList(bool activeOnly,product_strategy_t strategy,bool preferredDeviceOnly) const234 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
235                                                      bool preferredDeviceOnly) const
236 {
237     TrackClientVector clients;
238     for (const auto &client : getClientIterable()) {
239         if ((!activeOnly || client->active())
240             && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
241             && (!preferredDeviceOnly ||
242                 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
243             clients.push_back(client);
244         }
245     }
246     return clients;
247 }
248 
sameExclusivePreferredDevicesCount() const249 size_t AudioOutputDescriptor::sameExclusivePreferredDevicesCount() const
250 {
251     audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
252     size_t count = 0;
253     for (const auto &client : getClientIterable()) {
254         if (client->active()) {
255             if (!(client->hasPreferredDevice() &&
256                     client->isPreferredDeviceForExclusiveUse())) {
257                 return 0;
258             }
259             if (deviceId == AUDIO_PORT_HANDLE_NONE) {
260                 deviceId = client->preferredDeviceId();
261             } else if (deviceId != client->preferredDeviceId()) {
262                 return 0;
263             }
264             count++;
265         }
266     }
267     return count;
268 }
269 
isAnyActive(VolumeSource volumeSourceToIgnore) const270 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
271 {
272     return std::find_if(begin(mActiveClients), end(mActiveClients),
273                         [&volumeSourceToIgnore](const auto &client) {
274         return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
275 }
276 
dump(String8 * dst,int spaces,const char * extraInfo) const277 void AudioOutputDescriptor::dump(String8 *dst, int spaces, const char* extraInfo) const
278 {
279     dst->appendFormat("Port ID: %d%s%s\n",
280             mId, extraInfo != nullptr ? "; " : "", extraInfo != nullptr ? extraInfo : "");
281     dst->appendFormat("%*s%s; %d; Channel mask: 0x%x\n", spaces, "",
282             audio_format_to_string(mFormat), mSamplingRate, mChannelMask);
283     dst->appendFormat("%*sDevices: %s\n", spaces, "",
284             devices().toString(true /*includeSensitiveInfo*/).c_str());
285     dst->appendFormat("%*sGlobal active count: %u\n", spaces, "", mGlobalActiveCount);
286     if (!mRoutingActivities.empty()) {
287         dst->appendFormat("%*s- Product Strategies (%zu):\n", spaces - 2, "",
288                 mRoutingActivities.size());
289         for (const auto &iter : mRoutingActivities) {
290             dst->appendFormat("%*sid %d: ", spaces + 1, "", iter.first);
291             iter.second.dump(dst, 0);
292         }
293     }
294     if (!mVolumeActivities.empty()) {
295         dst->appendFormat("%*s- Volume Activities (%zu):\n", spaces - 2, "",
296                 mVolumeActivities.size());
297         for (const auto &iter : mVolumeActivities) {
298             dst->appendFormat("%*sid %d: ", spaces + 1, "", iter.first);
299             iter.second.dump(dst, 0);
300         }
301     }
302     if (getClientCount() != 0) {
303         dst->appendFormat("%*s- AudioTrack clients (%zu):\n", spaces - 2, "", getClientCount());
304         ClientMapHandler<TrackClientDescriptor>::dump(dst, spaces);
305     }
306     if (!mActiveClients.empty()) {
307         dst->appendFormat("%*s- AudioTrack active (stream) clients (%zu):\n", spaces - 2, "",
308                 mActiveClients.size());
309         size_t index = 0;
310         for (const auto& client : mActiveClients) {
311             const std::string prefix = base::StringPrintf(
312                     "%*sid %zu: ", spaces + 1, "", index + 1);
313             dst->appendFormat("%s", prefix.c_str());
314             client->dump(dst, prefix.size());
315         }
316     }
317 }
318 
log(const char * indent)319 void AudioOutputDescriptor::log(const char* indent)
320 {
321     ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
322           indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
323 }
324 
325 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)326 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
327                                                  AudioPolicyClientInterface *clientInterface)
328     : AudioOutputDescriptor(profile, clientInterface),
329     mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
330     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
331     mDirectClientSession(AUDIO_SESSION_NONE)
332 {
333     if (profile != nullptr) {
334         // By default, opening the output without immutable flags, the bit-perfect flags should be
335         // applied when the apps explicitly request.
336         mFlags = (audio_output_flags_t)(profile->getFlags() & (~AUDIO_OUTPUT_FLAG_BIT_PERFECT));
337     }
338 }
339 
dump(String8 * dst,int spaces,const char * extraInfo) const340 void SwAudioOutputDescriptor::dump(String8 *dst, int spaces, const char* extraInfo) const
341 {
342     String8 allExtraInfo;
343     if (extraInfo != nullptr) {
344         allExtraInfo.appendFormat("%s; ", extraInfo);
345     }
346     if (mProfile != nullptr) {
347         allExtraInfo.appendFormat("IOProfile name:%s; ", mProfile->getName().c_str());
348     }
349     std::string flagsLiteral = toString(mFlags);
350     allExtraInfo.appendFormat("Latency: %d; 0x%04x", mLatency, mFlags);
351     if (!flagsLiteral.empty()) {
352         allExtraInfo.appendFormat(" (%s)", flagsLiteral.c_str());
353     }
354     AudioOutputDescriptor::dump(dst, spaces, allExtraInfo.c_str());
355 }
356 
devices() const357 DeviceVector SwAudioOutputDescriptor::devices() const
358 {
359     if (isDuplicated()) {
360         DeviceVector devices = mOutput1->devices();
361         devices.merge(mOutput2->devices());
362         return devices;
363     }
364     return mDevices;
365 }
366 
sharesHwModuleWith(const sp<SwAudioOutputDescriptor> & outputDesc)367 bool SwAudioOutputDescriptor::sharesHwModuleWith(
368         const sp<SwAudioOutputDescriptor>& outputDesc)
369 {
370     if (isDuplicated()) {
371         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
372     } else if (outputDesc->isDuplicated()){
373         return sharesHwModuleWith(outputDesc->subOutput1()) ||
374                     sharesHwModuleWith(outputDesc->subOutput2());
375     } else {
376         return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
377     }
378 }
379 
supportedDevices() const380 DeviceVector SwAudioOutputDescriptor::supportedDevices() const
381 {
382     if (isDuplicated()) {
383         DeviceVector supportedDevices = mOutput1->supportedDevices();
384         supportedDevices.merge(mOutput2->supportedDevices());
385         return supportedDevices;
386     }
387     if (mProfile != nullptr) {
388         return mProfile->getSupportedDevices();
389     }
390     return DeviceVector();
391 }
392 
supportsDevice(const sp<DeviceDescriptor> & device) const393 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
394 {
395     return supportedDevices().contains(device);
396 }
397 
supportsAllDevices(const DeviceVector & devices) const398 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
399 {
400     return supportedDevices().containsAllDevices(devices);
401 }
402 
supportsAtLeastOne(const DeviceVector & devices) const403 bool SwAudioOutputDescriptor::supportsAtLeastOne(const DeviceVector &devices) const
404 {
405     return filterSupportedDevices(devices).size() > 0;
406 }
407 
supportsDevicesForPlayback(const DeviceVector & devices) const408 bool SwAudioOutputDescriptor::supportsDevicesForPlayback(const DeviceVector &devices) const
409 {
410     // No considering duplicated output
411     // TODO: need to verify if the profile supports the devices combo for playback.
412     return !isDuplicated() && supportsAllDevices(devices);
413 }
414 
filterSupportedDevices(const DeviceVector & devices) const415 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
416 {
417     DeviceVector filteredDevices = supportedDevices();
418     return filteredDevices.filter(devices);
419 }
420 
devicesSupportEncodedFormats(const DeviceTypeSet & deviceTypes)421 bool SwAudioOutputDescriptor::devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes)
422 {
423     if (isDuplicated()) {
424         return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
425                     || mOutput2->devicesSupportEncodedFormats(deviceTypes));
426     } else if (mProfile != nullptr) {
427        return mProfile->devicesSupportEncodedFormats(deviceTypes);
428     }
429     return false;
430 }
431 
containsSingleDeviceSupportingEncodedFormats(const sp<DeviceDescriptor> & device) const432 bool SwAudioOutputDescriptor::containsSingleDeviceSupportingEncodedFormats(
433         const sp<DeviceDescriptor>& device) const
434 {
435     if (isDuplicated()) {
436         return (mOutput1->containsSingleDeviceSupportingEncodedFormats(device) &&
437                 mOutput2->containsSingleDeviceSupportingEncodedFormats(device));
438     }
439     if (mProfile != nullptr) {
440         return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
441     }
442     return false;
443 }
444 
latency()445 uint32_t SwAudioOutputDescriptor::latency()
446 {
447     if (isDuplicated()) {
448         return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
449     } else {
450         return mLatency;
451     }
452 }
453 
setClientActive(const sp<TrackClientDescriptor> & client,bool active)454 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
455 {
456     // forward usage count change to attached outputs
457     if (isDuplicated()) {
458         mOutput1->setClientActive(client, active);
459         mOutput2->setClientActive(client, active);
460     }
461     AudioOutputDescriptor::setClientActive(client, active);
462 }
463 
isFixedVolume(const DeviceTypeSet & deviceTypes)464 bool SwAudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes)
465 {
466     // unit gain if rerouting to external policy
467     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
468         if (mPolicyMix != NULL) {
469             ALOGV("max gain when rerouting for output=%d", mIoHandle);
470             return true;
471         }
472     }
473     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
474         ALOGV("max gain when output device is telephony tx");
475         return true;
476     }
477     return false;
478 }
479 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const480 void SwAudioOutputDescriptor::toAudioPortConfig(
481                                                  struct audio_port_config *dstConfig,
482                                                  const struct audio_port_config *srcConfig) const
483 {
484 
485     ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
486     AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
487 
488     dstConfig->ext.mix.handle = mIoHandle;
489 }
490 
toAudioPort(struct audio_port_v7 * port) const491 void SwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
492 {
493     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
494 
495     AudioOutputDescriptor::toAudioPort(port);
496 
497     toAudioPortConfig(&port->active_config);
498     port->ext.mix.handle = mIoHandle;
499     port->ext.mix.latency_class =
500             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
501 }
502 
setSwMute(bool mutedByGroup,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs)503 void SwAudioOutputDescriptor::setSwMute(
504         bool mutedByGroup, VolumeSource vs, const StreamTypeVector &streamTypes,
505         const DeviceTypeSet& deviceTypes, uint32_t delayMs) {
506     // volume source active and more than one volume source is active, otherwise, no-op or let
507     // setVolume controlling SW and/or HW Gains
508     if (!audioserver_flags::portid_volume_management()) {
509         if (!streamTypes.empty() && isActive(vs) && (getActiveVolumeSources().size() > 1)) {
510             for (const auto& devicePort : devices()) {
511                 if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
512                     devicePort->hasGainController(true /*canUseForVolume*/)) {
513                     ALOGV("%s: output: %d, vs: %d, muted: %d, active vs count: %zu", __func__,
514                           mIoHandle, vs, mutedByGroup, getActiveVolumeSources().size());
515                     for (const auto &stream : streamTypes) {
516                         mClientInterface->setStreamVolume(stream, Volume::DbToAmpl(0), mutedByGroup,
517                                                           mIoHandle, delayMs);
518                     }
519                     return;
520                 }
521             }
522         }
523     } else {
524         if (isActive(vs) && (getActiveVolumeSources().size() > 1)) {
525             for (const auto &devicePort: devices()) {
526                 if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
527                     devicePort->hasGainController(true /*canUseForVolume*/)) {
528                     float volumeAmpl = Volume::DbToAmpl(0);
529                     ALOGV("%s: output: %d, vs: %d, muted: %d, active vs count: %zu", __func__,
530                           mIoHandle, vs, mutedByGroup, getActiveVolumeSources().size());
531                     mClientInterface->setPortsVolume(
532                             getPortsForVolumeSource(vs), Volume::DbToAmpl(0), mutedByGroup,
533                             mIoHandle, delayMs);
534                     return;
535                 }
536             }
537         }
538     }
539 }
540 
setVolume(float volumeDb,bool mutedByGroup,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force,bool isVoiceVolSrc)541 bool SwAudioOutputDescriptor::setVolume(float volumeDb, bool mutedByGroup,
542                                         VolumeSource vs, const StreamTypeVector &streamTypes,
543                                         const DeviceTypeSet& deviceTypes,
544                                         uint32_t delayMs,
545                                         bool force,
546                                         bool isVoiceVolSrc)
547 {
548     StreamTypeVector streams = streamTypes;
549     if (!AudioOutputDescriptor::setVolume(
550             volumeDb, mutedByGroup, vs, streamTypes, deviceTypes, delayMs, force, isVoiceVolSrc)) {
551         if (hasStream(streamTypes, AUDIO_STREAM_BLUETOOTH_SCO)) {
552             VolumeSource callVolSrc = getVoiceSource();
553             const bool mutedChanged =
554                     com_android_media_audio_ring_my_car() && hasVolumeSource(callVolSrc) &&
555                     (isMutedByGroup(callVolSrc) != mutedByGroup);
556             if (callVolSrc != VOLUME_SOURCE_NONE &&
557                 (volumeDb != getCurVolume(callVolSrc) || mutedChanged)) {
558                 setCurVolume(callVolSrc, volumeDb, mutedByGroup, true);
559                 float volumeAmpl = Volume::DbToAmpl(volumeDb);
560                 if (audioserver_flags::portid_volume_management()) {
561                     mClientInterface->setPortsVolume(getPortsForVolumeSource(callVolSrc),
562                             volumeAmpl, mutedByGroup, mIoHandle, delayMs);
563                 } else {
564                     mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL,
565                             volumeAmpl, mutedByGroup, mIoHandle, delayMs);
566                 }
567             }
568         }
569         return false;
570     }
571     if (streams.empty()) {
572         streams.push_back(AUDIO_STREAM_MUSIC);
573     }
574     for (const auto& devicePort : devices()) {
575         // APM loops on all group, so filter on active group to set the port gain,
576         // let the other groups set the sw volume as per legacy
577         // TODO: Pass in the device address and check against it.
578         if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
579                 devicePort->hasGainController(true) && isActive(vs)) {
580             ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
581             // @todo: here we might be in trouble if the SwOutput has several active clients with
582             // different Volume Source (or if we allow several curves within same volume group)
583             if (!audioserver_flags::portid_volume_management()) {
584                 // @todo: default stream volume to max (0) when using HW Port gain?
585                 // Allows to set SW Gain on AudioFlinger if:
586                 //    -volume group has explicit stream(s) associated
587                 //    -volume group with no explicit stream(s) is the only active source on this
588                 //    output
589                 // Allows to mute SW Gain on AudioFlinger only for volume group with explicit
590                 // stream(s)
591                 if (!streamTypes.empty() || (getActiveVolumeSources().size() == 1)) {
592                     const bool canMute = mutedByGroup && !streamTypes.empty();
593                     const float volumeAmpl = Volume::DbToAmpl(0);
594                     for (const auto &stream: streams) {
595                         mClientInterface->setStreamVolume(stream, volumeAmpl, canMute, mIoHandle,
596                                                           delayMs);
597                     }
598                 }
599             } else {
600                 float volumeAmpl = Volume::DbToAmpl(0);
601                 ALOGV("%s: output: %d, vs: %d, active vs count: %zu", __func__,
602                       mIoHandle, vs, getActiveVolumeSources().size());
603                 mClientInterface->setPortsVolume(
604                         getPortsForVolumeSource(vs), volumeAmpl, mutedByGroup, mIoHandle, delayMs);
605             }
606             AudioGains gains = devicePort->getGains();
607             int gainMinValueInMb = gains[0]->getMinValueInMb();
608             int gainMaxValueInMb = gains[0]->getMaxValueInMb();
609             int gainStepValueInMb = gains[0]->getStepValueInMb();
610             int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
611             gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
612 
613             audio_port_config config = {};
614             devicePort->toAudioPortConfig(&config);
615             config.config_mask = AUDIO_PORT_CONFIG_GAIN;
616             config.gain.mode = gains[0]->getMode();
617             config.gain.values[0] = gainValueMb;
618             return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
619         }
620     }
621     // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
622     float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
623     if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
624         VolumeSource callVolSrc = getVoiceSource();
625         if (audioserver_flags::portid_volume_management()) {
626             if (callVolSrc != VOLUME_SOURCE_NONE) {
627                 mClientInterface->setPortsVolume(getPortsForVolumeSource(callVolSrc), volumeAmpl,
628                                                  mutedByGroup, mIoHandle, delayMs);
629             }
630         } else {
631             mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mutedByGroup,
632                                               mIoHandle, delayMs);
633         }
634         if (callVolSrc != VOLUME_SOURCE_NONE) {
635             setCurVolume(callVolSrc, getCurVolume(vs), mutedByGroup, true);
636         }
637     }
638     if (audioserver_flags::portid_volume_management()) {
639         ALOGV("%s output %d for volumeSource %d, volume %f, mutedByGroup %d, delay %d active=%d",
640               __func__, mIoHandle, vs, volumeDb, mutedByGroup, delayMs, isActive(vs));
641         mClientInterface->setPortsVolume(getPortsForVolumeSource(vs), volumeAmpl, mutedByGroup,
642                                          mIoHandle, delayMs);
643     } else {
644         for (const auto &stream : streams) {
645             ALOGV("%s output %d for volumeSource %d, volume %f, mutedByGroup %d delay %d stream=%s",
646                   __func__, mIoHandle, vs, volumeDb, mutedByGroup, delayMs,
647                   toString(stream).c_str());
648             mClientInterface->setStreamVolume(stream, volumeAmpl, mutedByGroup, mIoHandle, delayMs);
649         }
650     }
651     return true;
652 }
653 
getPortsForVolumeSource(const VolumeSource & vs)654 std::vector<audio_port_handle_t> SwAudioOutputDescriptor::getPortsForVolumeSource(
655         const VolumeSource& vs)
656 {
657     std::vector<audio_port_handle_t> portsForVolumeSource;
658     for (const auto& client : getClientIterable()) {
659         if (client->volumeSource() == vs) {
660             portsForVolumeSource.push_back(client->portId());
661         }
662     }
663     return portsForVolumeSource;
664 }
665 
open(const audio_config_t * halConfig,const audio_config_base_t * mixerConfig,const DeviceVector & devices,audio_stream_type_t stream,audio_output_flags_t * flags,audio_io_handle_t * output,audio_attributes_t attributes)666 status_t SwAudioOutputDescriptor::open(const audio_config_t *halConfig,
667                                        const audio_config_base_t *mixerConfig,
668                                        const DeviceVector &devices,
669                                        audio_stream_type_t stream,
670                                        audio_output_flags_t *flags,
671                                        audio_io_handle_t *output,
672                                        audio_attributes_t attributes)
673 {
674     mDevices = devices;
675     sp<DeviceDescriptor> device = devices.getDeviceForOpening();
676     LOG_ALWAYS_FATAL_IF(device == nullptr,
677                         "%s failed to get device descriptor for opening "
678                         "with the requested devices, all device types: %s",
679                         __func__, dumpDeviceTypes(devices.types()).c_str());
680 
681     if (mProfile == nullptr) {
682         ALOGE("%s : Cannot open descriptor without a profile ", __func__);
683         return INVALID_OPERATION;
684     }
685 
686     audio_config_t lHalConfig;
687     if (halConfig == nullptr) {
688         lHalConfig = AUDIO_CONFIG_INITIALIZER;
689         lHalConfig.sample_rate = mSamplingRate;
690         lHalConfig.channel_mask = mChannelMask;
691         lHalConfig.format = mFormat;
692     } else {
693         lHalConfig = *halConfig;
694     }
695 
696     // if the selected profile is offloaded and no offload info was specified,
697     // create a default one
698     if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
699             lHalConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
700         *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
701         lHalConfig.offload_info = AUDIO_INFO_INITIALIZER;
702         lHalConfig.offload_info.sample_rate = lHalConfig.sample_rate;
703         lHalConfig.offload_info.channel_mask = lHalConfig.channel_mask;
704         lHalConfig.offload_info.format = lHalConfig.format;
705         lHalConfig.offload_info.stream_type = stream;
706     }
707 
708     audio_config_base_t lMixerConfig;
709     if (mixerConfig == nullptr) {
710         lMixerConfig = AUDIO_CONFIG_BASE_INITIALIZER;
711         lMixerConfig.sample_rate = lHalConfig.sample_rate;
712         lMixerConfig.channel_mask = lHalConfig.channel_mask;
713         lMixerConfig.format = lHalConfig.format;
714     } else {
715         lMixerConfig = *mixerConfig;
716     }
717 
718     mFlags = (audio_output_flags_t)(mFlags | *flags);
719 
720     // If no mixer config is specified for a spatializer output, default to 5.1 for proper
721     // configuration of the final downmixer or spatializer
722     if ((mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0
723             && mixerConfig == nullptr) {
724         lMixerConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
725     }
726 
727     ALOGV("opening output for device %s profile %p name %s",
728           mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str());
729 
730     status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
731                                                    output,
732                                                    &lHalConfig,
733                                                    &lMixerConfig,
734                                                    device,
735                                                    &mLatency,
736                                                    &mFlags,
737                                                    attributes);
738     *flags = mFlags;
739 
740     if (status == NO_ERROR) {
741         LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
742                             "%s openOutput returned output handle %d for device %s, "
743                             "selected device %s for opening",
744                             __FUNCTION__, *output, devices.toString().c_str(),
745                             device->toString().c_str());
746         mSamplingRate = lHalConfig.sample_rate;
747         mChannelMask = lHalConfig.channel_mask;
748         mFormat = lHalConfig.format;
749         mMixerChannelMask = lMixerConfig.channel_mask;
750         mId = PolicyAudioPort::getNextUniqueId();
751         mIoHandle = *output;
752         mProfile->curOpenCount++;
753     }
754 
755     return status;
756 }
757 
start()758 status_t SwAudioOutputDescriptor::start()
759 {
760     if (isDuplicated()) {
761         status_t status = mOutput1->start();
762         if (status != NO_ERROR) {
763             return status;
764         }
765         status = mOutput2->start();
766         if (status != NO_ERROR) {
767             mOutput1->stop();
768             return status;
769         }
770         return NO_ERROR;
771     }
772     if (mProfile != nullptr && !isActive()) {
773         if (!mProfile->canStartNewIo()) {
774             return INVALID_OPERATION;
775         }
776         mProfile->curActiveCount++;
777     }
778     return NO_ERROR;
779 }
780 
stop()781 void SwAudioOutputDescriptor::stop()
782 {
783     if (isDuplicated()) {
784         mOutput1->stop();
785         mOutput2->stop();
786         return;
787     }
788 
789     if (mProfile != nullptr && !isActive()) {
790         LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
791                             "%s invalid profile active count %u",
792                             __func__, mProfile->curActiveCount);
793         mProfile->curActiveCount--;
794     }
795 }
796 
close()797 void SwAudioOutputDescriptor::close()
798 {
799     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
800         // clean up active clients if any (can happen if close() is called to force
801         // clients to reconnect
802         for (const auto &client : getClientIterable()) {
803             if (client->active()) {
804                 ALOGW("%s client with port ID %d still active on output %d",
805                       __func__, client->portId(), mId);
806                 setClientActive(client, false);
807                 stop();
808             }
809         }
810 
811         mClientInterface->closeOutput(mIoHandle);
812         if (mProfile != nullptr) {
813             LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
814                                 __FUNCTION__, mProfile->curOpenCount);
815             mProfile->curOpenCount--;
816         }
817         mIoHandle = AUDIO_IO_HANDLE_NONE;
818     }
819 }
820 
openDuplicating(const sp<SwAudioOutputDescriptor> & output1,const sp<SwAudioOutputDescriptor> & output2,audio_io_handle_t * ioHandle)821 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
822                                                   const sp<SwAudioOutputDescriptor>& output2,
823                                                   audio_io_handle_t *ioHandle)
824 {
825     // open a duplicating output thread for the new output and the primary output
826     // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
827     // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
828     *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
829     if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
830         return INVALID_OPERATION;
831     }
832 
833     mId = PolicyAudioPort::getNextUniqueId();
834     mIoHandle = *ioHandle;
835     mOutput1 = output1;
836     mOutput2 = output2;
837     mSamplingRate = output2->mSamplingRate;
838     mFormat = output2->mFormat;
839     mChannelMask = output2->mChannelMask;
840     mLatency = output2->mLatency;
841 
842     return NO_ERROR;
843 }
844 
getRecommendedMuteDurationMs() const845 uint32_t SwAudioOutputDescriptor::getRecommendedMuteDurationMs() const
846 {
847     if (isDuplicated()) {
848         return std::max(mOutput1->getRecommendedMuteDurationMs(),
849                 mOutput2->getRecommendedMuteDurationMs());
850     }
851     if (mProfile != nullptr) {
852         return mProfile->recommendedMuteDurationMs;
853     }
854     return 0;
855 }
856 
setTracksInvalidatedStatusByStrategy(product_strategy_t strategy)857 void SwAudioOutputDescriptor::setTracksInvalidatedStatusByStrategy(product_strategy_t strategy) {
858     for (const auto &client : getClientIterable()) {
859         if (strategy == client->strategy()) {
860             client->setIsInvalid();
861         }
862     }
863 }
864 
setDevices(const android::DeviceVector & devices)865 void SwAudioOutputDescriptor::setDevices(const android::DeviceVector &devices) {
866     if ((mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) == AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
867         for (auto device : mDevices) {
868             device->setPreferredConfig(nullptr);
869         }
870         auto config = getConfig();
871         for (auto device : devices) {
872             device->setPreferredConfig(&config);
873         }
874     }
875     mDevices = devices;
876 }
877 
isUsageActiveOnDevice(audio_usage_t usage,sp<android::DeviceDescriptor> device) const878 bool SwAudioOutputDescriptor::isUsageActiveOnDevice(audio_usage_t usage,
879                                                     sp<android::DeviceDescriptor> device) const {
880     if (device != nullptr && !mDevices.contains(device)) {
881         return false;
882     }
883     return std::any_of(mActiveClients.begin(), mActiveClients.end(),
884                        [usage](sp<TrackClientDescriptor> client) {
885                            return client->attributes().usage == usage; });
886 }
887 
888 // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor(const sp<SourceClientDescriptor> & source,AudioPolicyClientInterface * clientInterface)889 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
890                                                  AudioPolicyClientInterface *clientInterface)
891     : AudioOutputDescriptor(source->srcDevice(), clientInterface),
892       mSource(source)
893 {
894 }
895 
dump(String8 * dst,int spaces,const char * extraInfo) const896 void HwAudioOutputDescriptor::dump(String8 *dst, int spaces, const char* extraInfo) const
897 {
898     AudioOutputDescriptor::dump(dst, spaces, extraInfo);
899     dst->appendFormat("%*sSource:\n", spaces, "");
900     mSource->dump(dst, spaces);
901 }
902 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const903 void HwAudioOutputDescriptor::toAudioPortConfig(
904                                                  struct audio_port_config *dstConfig,
905                                                  const struct audio_port_config *srcConfig) const
906 {
907     mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
908 }
909 
toAudioPort(struct audio_port_v7 * port) const910 void HwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
911 {
912     mSource->srcDevice()->toAudioPort(port);
913 }
914 
915 
setVolume(float volumeDb,bool muted,VolumeSource volumeSource,const StreamTypeVector & streams,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force,bool isVoiceVolSrc)916 bool HwAudioOutputDescriptor::setVolume(float volumeDb, bool muted,
917                                         VolumeSource volumeSource, const StreamTypeVector &streams,
918                                         const DeviceTypeSet& deviceTypes,
919                                         uint32_t delayMs,
920                                         bool force,
921                                         bool isVoiceVolSrc)
922 {
923     bool changed = AudioOutputDescriptor::setVolume(
924             volumeDb, muted, volumeSource, streams, deviceTypes, delayMs, force, isVoiceVolSrc);
925 
926     if (changed) {
927       // TODO: use gain controller on source device if any to adjust volume
928     }
929     return changed;
930 }
931 
932 // SwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const933 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
934 {
935     nsecs_t sysTime = systemTime();
936     for (size_t i = 0; i < this->size(); i++) {
937         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
938         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
939             return true;
940         }
941     }
942     return false;
943 }
944 
isActiveLocally(VolumeSource volumeSource,uint32_t inPastMs) const945 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
946 {
947     nsecs_t sysTime = systemTime();
948     for (size_t i = 0; i < this->size(); i++) {
949         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
950         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
951                 && (!(outputDesc->devices()
952                         .containsDeviceAmongTypes(getAllOutRemoteDevices())
953                         || outputDesc->devices()
954                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)))) {
955             return true;
956         }
957     }
958     return false;
959 }
960 
isActiveRemotely(VolumeSource volumeSource,uint32_t inPastMs) const961 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
962 {
963     nsecs_t sysTime = systemTime();
964     for (size_t i = 0; i < size(); i++) {
965         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
966         if (outputDesc->devices().containsDeviceAmongTypes(getAllOutRemoteDevices()) &&
967                 outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
968             // do not consider re routing (when the output is going to a dynamic policy)
969             // as "remote playback"
970             if (outputDesc->mPolicyMix == NULL) {
971                 return true;
972             }
973         }
974     }
975     return false;
976 }
977 
isStrategyActiveOnSameModule(product_strategy_t ps,const sp<SwAudioOutputDescriptor> & desc,uint32_t inPastMs,nsecs_t sysTime) const978 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
979                                                            const sp<SwAudioOutputDescriptor>& desc,
980                                                            uint32_t inPastMs, nsecs_t sysTime) const
981 {
982     for (size_t i = 0; i < size(); i++) {
983         const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
984         if (desc->sharesHwModuleWith(otherDesc) &&
985                 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
986             if (desc == otherDesc
987                     || !otherDesc->devices()
988                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
989                 return true;
990             }
991         }
992     }
993     return false;
994 }
995 
isStrategyActive(product_strategy_t ps) const996 bool SwAudioOutputCollection::isStrategyActive(product_strategy_t ps) const
997 {
998     for (size_t i = 0; i < size(); i++) {
999         if (valueAt(i)->isStrategyActive(ps)) {
1000             return true;
1001         }
1002     }
1003     return false;
1004 }
1005 
getA2dpOutput() const1006 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
1007 {
1008     for (size_t i = 0; i < size(); i++) {
1009         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
1010         if (!outputDesc->isDuplicated() &&
1011              outputDesc->devices().containsDeviceAmongTypes(getAudioDeviceOutAllA2dpSet()) &&
1012              outputDesc->devicesSupportEncodedFormats(getAudioDeviceOutAllA2dpSet())) {
1013             return this->keyAt(i);
1014         }
1015     }
1016     return 0;
1017 }
1018 
isA2dpOffloadedOnPrimary() const1019 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
1020 {
1021     sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
1022 
1023     if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
1024         && (primaryOutput->mProfile->getModule() != NULL)) {
1025         sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
1026 
1027         for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
1028             if (outputProfile->supportsDeviceTypes(getAudioDeviceOutAllA2dpSet())) {
1029                 return true;
1030             }
1031         }
1032     }
1033     return false;
1034 }
1035 
getPrimaryOutput() const1036 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
1037 {
1038     for (size_t i = 0; i < size(); i++) {
1039         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
1040         if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
1041             return outputDesc;
1042         }
1043     }
1044     return NULL;
1045 }
1046 
getOutputFromId(audio_port_handle_t id) const1047 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
1048 {
1049     for (size_t i = 0; i < size(); i++) {
1050         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
1051         if (outputDesc->getId() == id) {
1052             return outputDesc;
1053         }
1054     }
1055     return NULL;
1056 }
1057 
getOutputForClient(audio_port_handle_t portId)1058 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
1059 {
1060     for (size_t i = 0; i < size(); i++) {
1061         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
1062         if (outputDesc->getClient(portId) != nullptr) {
1063             return outputDesc;
1064         }
1065     }
1066     return 0;
1067 }
1068 
clearSessionRoutesForDevice(const sp<DeviceDescriptor> & disconnectedDevice)1069 void SwAudioOutputCollection::clearSessionRoutesForDevice(
1070         const sp<DeviceDescriptor> &disconnectedDevice)
1071 {
1072     for (size_t i = 0; i < size(); i++) {
1073         sp<AudioOutputDescriptor> outputDesc = valueAt(i);
1074         for (const auto& client : outputDesc->getClientIterable()) {
1075             if (client->preferredDeviceId() == disconnectedDevice->getId()) {
1076                 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
1077             }
1078         }
1079     }
1080 }
isAnyDeviceTypeActive(const DeviceTypeSet & deviceTypes) const1081 bool SwAudioOutputCollection::isAnyDeviceTypeActive(const DeviceTypeSet& deviceTypes) const {
1082     for (size_t i = 0; i < size(); i++) {
1083         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
1084         if (outputDesc->isActive()
1085                 && outputDesc->devices().containsDeviceAmongTypes(deviceTypes)) {
1086             return true;
1087         }
1088     }
1089     return false;
1090 }
1091 
isConfigurationMatched(const audio_config_base_t & config,audio_output_flags_t flags)1092 bool SwAudioOutputDescriptor::isConfigurationMatched(const audio_config_base_t &config,
1093                                                      audio_output_flags_t flags) {
1094     const uint32_t mustMatchOutputFlags =
1095             AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
1096     return audio_output_flags_is_subset(AudioOutputDescriptor::mFlags, flags, mustMatchOutputFlags)
1097             && mSamplingRate == config.sample_rate
1098             && mChannelMask == config.channel_mask
1099             && mFormat == config.format;
1100 }
1101 
getClientsForStream(audio_stream_type_t streamType) const1102 PortHandleVector SwAudioOutputDescriptor::getClientsForStream(
1103         audio_stream_type_t streamType) const {
1104     PortHandleVector clientsForStream;
1105     for (const auto& client : getClientIterable()) {
1106         if (client->stream() == streamType) {
1107             clientsForStream.push_back(client->portId());
1108         }
1109     }
1110     return clientsForStream;
1111 }
1112 
isUsageActiveOnDevice(audio_usage_t usage,sp<android::DeviceDescriptor> device) const1113 bool SwAudioOutputCollection::isUsageActiveOnDevice(audio_usage_t usage,
1114                                                     sp<android::DeviceDescriptor> device) const {
1115     for (size_t i = 0; i < this->size(); i++) {
1116         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
1117         if (outputDesc->isUsageActiveOnDevice(usage, device)) {
1118             return true;
1119         }
1120     }
1121     return false;
1122 }
1123 
info() const1124 std::string SwAudioOutputDescriptor::info() const {
1125     std::string result;
1126     result.append("[" );
1127     result.append(AudioOutputDescriptor::info());
1128     result.append("[io:" );
1129     result.append(android::internal::ToString(mIoHandle));
1130     result.append(", " );
1131     result.append(isDuplicated() ? "duplicating" : mProfile->getTagName());
1132     result.append("]]");
1133     return result;
1134 }
1135 
dump(String8 * dst) const1136 void SwAudioOutputCollection::dump(String8 *dst) const
1137 {
1138     dst->appendFormat("\n Outputs (%zu):\n", size());
1139     for (size_t i = 0; i < size(); i++) {
1140         const std::string prefix = base::StringPrintf("  %zu. ", i + 1);
1141         const std::string extraInfo = base::StringPrintf("I/O handle: %d", keyAt(i));
1142         dst->appendFormat("%s", prefix.c_str());
1143         valueAt(i)->dump(dst, prefix.size(), extraInfo.c_str());
1144     }
1145 }
1146 
1147 // HwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const1148 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
1149 {
1150     nsecs_t sysTime = systemTime();
1151     for (size_t i = 0; i < this->size(); i++) {
1152         const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
1153         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
1154             return true;
1155         }
1156     }
1157     return false;
1158 }
1159 
dump(String8 * dst) const1160 void HwAudioOutputCollection::dump(String8 *dst) const
1161 {
1162     dst->appendFormat("\n Outputs (%zu):\n", size());
1163     for (size_t i = 0; i < size(); i++) {
1164         const std::string prefix = base::StringPrintf("  %zu. ", i + 1);
1165         const std::string extraInfo = base::StringPrintf("I/O handle: %d", keyAt(i));
1166         dst->appendFormat("%s", prefix.c_str());
1167         valueAt(i)->dump(dst, prefix.size(), extraInfo.c_str());
1168     }
1169 }
1170 
1171 }; //namespace android
1172