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