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