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