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 <AudioPolicyInterface.h>
21 #include "AudioOutputDescriptor.h"
22 #include "AudioPolicyMix.h"
23 #include "IOProfile.h"
24 #include "Volume.h"
25 #include "HwModule.h"
26 #include "TypeConverter.h"
27 #include <media/AudioGain.h>
28 #include <media/AudioParameter.h>
29 #include <media/AudioPolicy.h>
30
31 // A device mask for all audio output devices that are considered "remote" when evaluating
32 // active output devices in isStreamActiveRemotely()
33
34 namespace android {
35
getAllOutRemoteDevices()36 static const DeviceTypeSet& getAllOutRemoteDevices() {
37 static const DeviceTypeSet allOutRemoteDevices = {AUDIO_DEVICE_OUT_REMOTE_SUBMIX};
38 return allOutRemoteDevices;
39 }
40
AudioOutputDescriptor(const sp<PolicyAudioPort> & policyAudioPort,AudioPolicyClientInterface * clientInterface)41 AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
42 AudioPolicyClientInterface *clientInterface)
43 : mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
44 {
45 if (mPolicyAudioPort.get() != nullptr) {
46 mPolicyAudioPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
47 if (mPolicyAudioPort->asAudioPort()->getGains().size() > 0) {
48 mPolicyAudioPort->asAudioPort()->getGains()[0]->getDefaultConfig(&mGain);
49 }
50 }
51 }
52
getConfig() const53 audio_config_base_t AudioOutputDescriptor::getConfig() const
54 {
55 const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
56 .format = mFormat };
57 return config;
58 }
59
getModuleHandle() const60 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
61 {
62 return mPolicyAudioPort.get() != nullptr ?
63 mPolicyAudioPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
64 }
65
getPatchHandle() const66 audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
67 {
68 return mPatchHandle;
69 }
70
setPatchHandle(audio_patch_handle_t handle)71 void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
72 {
73 mPatchHandle = handle;
74 }
75
sharesHwModuleWith(const sp<AudioOutputDescriptor> & outputDesc)76 bool AudioOutputDescriptor::sharesHwModuleWith(
77 const sp<AudioOutputDescriptor>& outputDesc)
78 {
79 return hasSameHwModuleAs(outputDesc);
80 }
81
setStopTime(const sp<TrackClientDescriptor> & client,nsecs_t sysTime)82 void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
83 {
84 mVolumeActivities[client->volumeSource()].setStopTime(sysTime);
85 mRoutingActivities[client->strategy()].setStopTime(sysTime);
86 }
87
setClientActive(const sp<TrackClientDescriptor> & client,bool active)88 void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
89 {
90 auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client);
91 if (active == (clientIter != end(mActiveClients))) {
92 ALOGW("%s(%s): ignored active: %d, current stream count %d", __func__,
93 client->toShortString().c_str(), active,
94 mRoutingActivities.at(client->strategy()).getActivityCount());
95 return;
96 }
97 if (active) {
98 mActiveClients.push_back(client);
99 } else {
100 mActiveClients.erase(clientIter);
101 }
102 const int delta = active ? 1 : -1;
103 // If ps is unknown, it is time to track it!
104 mRoutingActivities[client->strategy()].changeActivityCount(delta);
105 mVolumeActivities[client->volumeSource()].changeActivityCount(delta);
106
107 // Handle non-client-specific activity ref count
108 int32_t oldGlobalActiveCount = mGlobalActiveCount;
109 if (!active && mGlobalActiveCount < 1) {
110 ALOGW("%s(%s): invalid deactivation with globalRefCount %d",
111 __func__, client->toShortString().c_str(), mGlobalActiveCount);
112 mGlobalActiveCount = 1;
113 }
114 mGlobalActiveCount += delta;
115
116 sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
117 if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
118 if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) {
119 mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
120 mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE);
121 }
122 }
123 client->setActive(active);
124 }
125
isActive(VolumeSource vs,uint32_t inPastMs,nsecs_t sysTime) const126 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
127 {
128 return (vs == VOLUME_SOURCE_NONE) ?
129 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
130 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
131 }
132
isActive(uint32_t inPastMs) const133 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
134 {
135 nsecs_t sysTime = 0;
136 if (inPastMs != 0) {
137 sysTime = systemTime();
138 }
139 for (const auto &iter : mVolumeActivities) {
140 if (iter.second.isActive(inPastMs, sysTime)) {
141 return true;
142 }
143 }
144 return false;
145 }
146
isFixedVolume(const DeviceTypeSet & deviceTypes __unused)147 bool AudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes __unused)
148 {
149 return false;
150 }
151
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector &,const DeviceTypeSet &,uint32_t delayMs,bool force)152 bool AudioOutputDescriptor::setVolume(float volumeDb,
153 VolumeSource volumeSource,
154 const StreamTypeVector &/*streams*/,
155 const DeviceTypeSet& /*deviceTypes*/,
156 uint32_t delayMs,
157 bool force)
158 {
159 // We actually change the volume if:
160 // - the float value returned by computeVolume() changed
161 // - the force flag is set
162 if (volumeDb != getCurVolume(volumeSource) || force) {
163 ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
164 setCurVolume(volumeSource, volumeDb);
165 return true;
166 }
167 return false;
168 }
169
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)170 status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
171 audio_port_config *backupConfig)
172 {
173 struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
174 status_t status = NO_ERROR;
175
176 toAudioPortConfig(&localBackupConfig);
177 if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
178 AudioPortConfig::applyAudioPortConfig(config, backupConfig);
179 applyPolicyAudioPortConfig(config);
180 }
181
182 if (backupConfig != NULL) {
183 *backupConfig = localBackupConfig;
184 }
185 return status;
186 }
187
188
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const189 void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
190 const struct audio_port_config *srcConfig) const
191 {
192 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
193 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
194 if (srcConfig != NULL) {
195 dstConfig->config_mask |= srcConfig->config_mask;
196 }
197 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
198 toPolicyAudioPortConfig(dstConfig, srcConfig);
199
200 dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
201 dstConfig->type = AUDIO_PORT_TYPE_MIX;
202 dstConfig->ext.mix.hw_module = getModuleHandle();
203 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
204 }
205
toAudioPort(struct audio_port * port) const206 void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const
207 {
208 // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
209 mPolicyAudioPort->asAudioPort()->toAudioPort(port);
210 port->id = mId;
211 port->ext.mix.hw_module = getModuleHandle();
212 }
213
clientsList(bool activeOnly,product_strategy_t strategy,bool preferredDeviceOnly) const214 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
215 bool preferredDeviceOnly) const
216 {
217 TrackClientVector clients;
218 for (const auto &client : getClientIterable()) {
219 if ((!activeOnly || client->active())
220 && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
221 && (!preferredDeviceOnly ||
222 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
223 clients.push_back(client);
224 }
225 }
226 return clients;
227 }
228
isAnyActive(VolumeSource volumeSourceToIgnore) const229 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
230 {
231 return std::find_if(begin(mActiveClients), end(mActiveClients),
232 [&volumeSourceToIgnore](const auto &client) {
233 return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
234 }
235
dump(String8 * dst) const236 void AudioOutputDescriptor::dump(String8 *dst) const
237 {
238 dst->appendFormat(" ID: %d\n", mId);
239 dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
240 dst->appendFormat(" Format: %08x\n", mFormat);
241 dst->appendFormat(" Channels: %08x\n", mChannelMask);
242 dst->appendFormat(" Devices: %s\n", devices().toString().c_str());
243 dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
244 for (const auto &iter : mRoutingActivities) {
245 dst->appendFormat(" Product Strategy id: %d", iter.first);
246 iter.second.dump(dst, 4);
247 }
248 for (const auto &iter : mVolumeActivities) {
249 dst->appendFormat(" Volume Activities id: %d", iter.first);
250 iter.second.dump(dst, 4);
251 }
252 dst->append(" AudioTrack Clients:\n");
253 ClientMapHandler<TrackClientDescriptor>::dump(dst);
254 dst->append("\n");
255 if (!mActiveClients.empty()) {
256 dst->append(" AudioTrack active (stream) clients:\n");
257 size_t index = 0;
258 for (const auto& client : mActiveClients) {
259 client->dump(dst, 2, index++);
260 }
261 dst->append(" \n");
262 }
263 }
264
log(const char * indent)265 void AudioOutputDescriptor::log(const char* indent)
266 {
267 ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
268 indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
269 }
270
271 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)272 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
273 AudioPolicyClientInterface *clientInterface)
274 : AudioOutputDescriptor(profile, clientInterface),
275 mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
276 mFlags((audio_output_flags_t)0),
277 mOutput1(0), mOutput2(0), mDirectOpenCount(0),
278 mDirectClientSession(AUDIO_SESSION_NONE)
279 {
280 if (profile != NULL) {
281 mFlags = (audio_output_flags_t)profile->getFlags();
282 }
283 }
284
dump(String8 * dst) const285 void SwAudioOutputDescriptor::dump(String8 *dst) const
286 {
287 dst->appendFormat(" Latency: %d\n", mLatency);
288 dst->appendFormat(" Flags %08x\n", mFlags);
289 AudioOutputDescriptor::dump(dst);
290 }
291
devices() const292 DeviceVector SwAudioOutputDescriptor::devices() const
293 {
294 if (isDuplicated()) {
295 DeviceVector devices = mOutput1->devices();
296 devices.merge(mOutput2->devices());
297 return devices;
298 }
299 return mDevices;
300 }
301
sharesHwModuleWith(const sp<SwAudioOutputDescriptor> & outputDesc)302 bool SwAudioOutputDescriptor::sharesHwModuleWith(
303 const sp<SwAudioOutputDescriptor>& outputDesc)
304 {
305 if (isDuplicated()) {
306 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
307 } else if (outputDesc->isDuplicated()){
308 return sharesHwModuleWith(outputDesc->subOutput1()) ||
309 sharesHwModuleWith(outputDesc->subOutput2());
310 } else {
311 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
312 }
313 }
314
supportedDevices() const315 DeviceVector SwAudioOutputDescriptor::supportedDevices() const
316 {
317 if (isDuplicated()) {
318 DeviceVector supportedDevices = mOutput1->supportedDevices();
319 supportedDevices.merge(mOutput2->supportedDevices());
320 return supportedDevices;
321 }
322 return mProfile->getSupportedDevices();
323 }
324
supportsDevice(const sp<DeviceDescriptor> & device) const325 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
326 {
327 return supportedDevices().contains(device);
328 }
329
supportsAllDevices(const DeviceVector & devices) const330 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
331 {
332 return supportedDevices().containsAllDevices(devices);
333 }
334
filterSupportedDevices(const DeviceVector & devices) const335 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
336 {
337 DeviceVector filteredDevices = supportedDevices();
338 return filteredDevices.filter(devices);
339 }
340
devicesSupportEncodedFormats(const DeviceTypeSet & deviceTypes)341 bool SwAudioOutputDescriptor::devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes)
342 {
343 if (isDuplicated()) {
344 return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
345 || mOutput2->devicesSupportEncodedFormats(deviceTypes));
346 } else {
347 return mProfile->devicesSupportEncodedFormats(deviceTypes);
348 }
349 }
350
latency()351 uint32_t SwAudioOutputDescriptor::latency()
352 {
353 if (isDuplicated()) {
354 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
355 } else {
356 return mLatency;
357 }
358 }
359
setClientActive(const sp<TrackClientDescriptor> & client,bool active)360 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
361 {
362 // forward usage count change to attached outputs
363 if (isDuplicated()) {
364 mOutput1->setClientActive(client, active);
365 mOutput2->setClientActive(client, active);
366 }
367 AudioOutputDescriptor::setClientActive(client, active);
368 }
369
isFixedVolume(const DeviceTypeSet & deviceTypes)370 bool SwAudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes)
371 {
372 // unit gain if rerouting to external policy
373 if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
374 if (mPolicyMix != NULL) {
375 ALOGV("max gain when rerouting for output=%d", mIoHandle);
376 return true;
377 }
378 }
379 if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
380 ALOGV("max gain when output device is telephony tx");
381 return true;
382 }
383 return false;
384 }
385
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const386 void SwAudioOutputDescriptor::toAudioPortConfig(
387 struct audio_port_config *dstConfig,
388 const struct audio_port_config *srcConfig) const
389 {
390
391 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
392 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
393
394 dstConfig->ext.mix.handle = mIoHandle;
395 }
396
toAudioPort(struct audio_port * port) const397 void SwAudioOutputDescriptor::toAudioPort(
398 struct audio_port *port) const
399 {
400 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
401
402 AudioOutputDescriptor::toAudioPort(port);
403
404 toAudioPortConfig(&port->active_config);
405 port->ext.mix.handle = mIoHandle;
406 port->ext.mix.latency_class =
407 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
408 }
409
setVolume(float volumeDb,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)410 bool SwAudioOutputDescriptor::setVolume(float volumeDb,
411 VolumeSource vs, const StreamTypeVector &streamTypes,
412 const DeviceTypeSet& deviceTypes,
413 uint32_t delayMs,
414 bool force)
415 {
416 StreamTypeVector streams = streamTypes;
417 if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, deviceTypes, delayMs, force)) {
418 return false;
419 }
420 if (streams.empty()) {
421 streams.push_back(AUDIO_STREAM_MUSIC);
422 }
423 for (const auto& devicePort : devices()) {
424 // APM loops on all group, so filter on active group to set the port gain,
425 // let the other groups set the stream volume as per legacy
426 // TODO: Pass in the device address and check against it.
427 if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
428 devicePort->hasGainController(true) && isActive(vs)) {
429 ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
430 // @todo: here we might be in trouble if the SwOutput has several active clients with
431 // different Volume Source (or if we allow several curves within same volume group)
432 //
433 // @todo: default stream volume to max (0) when using HW Port gain?
434 float volumeAmpl = Volume::DbToAmpl(0);
435 for (const auto &stream : streams) {
436 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
437 }
438
439 AudioGains gains = devicePort->getGains();
440 int gainMinValueInMb = gains[0]->getMinValueInMb();
441 int gainMaxValueInMb = gains[0]->getMaxValueInMb();
442 int gainStepValueInMb = gains[0]->getStepValueInMb();
443 int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
444 gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
445
446 audio_port_config config = {};
447 devicePort->toAudioPortConfig(&config);
448 config.config_mask = AUDIO_PORT_CONFIG_GAIN;
449 config.gain.values[0] = gainValueMb;
450 return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
451 }
452 }
453 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
454 float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
455 if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
456 mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
457 }
458 for (const auto &stream : streams) {
459 ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
460 mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
461 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
462 }
463 return true;
464 }
465
open(const audio_config_t * config,const DeviceVector & devices,audio_stream_type_t stream,audio_output_flags_t flags,audio_io_handle_t * output)466 status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
467 const DeviceVector &devices,
468 audio_stream_type_t stream,
469 audio_output_flags_t flags,
470 audio_io_handle_t *output)
471 {
472 mDevices = devices;
473 sp<DeviceDescriptor> device = devices.getDeviceForOpening();
474 LOG_ALWAYS_FATAL_IF(device == nullptr,
475 "%s failed to get device descriptor for opening "
476 "with the requested devices, all device types: %s",
477 __func__, dumpDeviceTypes(devices.types()).c_str());
478
479 audio_config_t lConfig;
480 if (config == nullptr) {
481 lConfig = AUDIO_CONFIG_INITIALIZER;
482 lConfig.sample_rate = mSamplingRate;
483 lConfig.channel_mask = mChannelMask;
484 lConfig.format = mFormat;
485 } else {
486 lConfig = *config;
487 }
488
489 // if the selected profile is offloaded and no offload info was specified,
490 // create a default one
491 if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
492 lConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
493 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
494 lConfig.offload_info = AUDIO_INFO_INITIALIZER;
495 lConfig.offload_info.sample_rate = lConfig.sample_rate;
496 lConfig.offload_info.channel_mask = lConfig.channel_mask;
497 lConfig.offload_info.format = lConfig.format;
498 lConfig.offload_info.stream_type = stream;
499 lConfig.offload_info.duration_us = -1;
500 lConfig.offload_info.has_video = true; // conservative
501 lConfig.offload_info.is_streaming = true; // likely
502 }
503
504 mFlags = (audio_output_flags_t)(mFlags | flags);
505
506 ALOGV("opening output for device %s profile %p name %s",
507 mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str());
508
509 status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
510 output,
511 &lConfig,
512 device,
513 &mLatency,
514 mFlags);
515
516 if (status == NO_ERROR) {
517 LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
518 "%s openOutput returned output handle %d for device %s, "
519 "selected device %s for opening",
520 __FUNCTION__, *output, devices.toString().c_str(),
521 device->toString().c_str());
522 mSamplingRate = lConfig.sample_rate;
523 mChannelMask = lConfig.channel_mask;
524 mFormat = lConfig.format;
525 mId = PolicyAudioPort::getNextUniqueId();
526 mIoHandle = *output;
527 mProfile->curOpenCount++;
528 }
529
530 return status;
531 }
532
start()533 status_t SwAudioOutputDescriptor::start()
534 {
535 if (isDuplicated()) {
536 status_t status = mOutput1->start();
537 if (status != NO_ERROR) {
538 return status;
539 }
540 status = mOutput2->start();
541 if (status != NO_ERROR) {
542 mOutput1->stop();
543 return status;
544 }
545 return NO_ERROR;
546 }
547 if (!isActive()) {
548 if (!mProfile->canStartNewIo()) {
549 return INVALID_OPERATION;
550 }
551 mProfile->curActiveCount++;
552 }
553 return NO_ERROR;
554 }
555
stop()556 void SwAudioOutputDescriptor::stop()
557 {
558 if (isDuplicated()) {
559 mOutput1->stop();
560 mOutput2->stop();
561 return;
562 }
563
564 if (!isActive()) {
565 LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
566 "%s invalid profile active count %u",
567 __func__, mProfile->curActiveCount);
568 mProfile->curActiveCount--;
569 }
570 }
571
close()572 void SwAudioOutputDescriptor::close()
573 {
574 if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
575 // clean up active clients if any (can happen if close() is called to force
576 // clients to reconnect
577 for (const auto &client : getClientIterable()) {
578 if (client->active()) {
579 ALOGW("%s client with port ID %d still active on output %d",
580 __func__, client->portId(), mId);
581 setClientActive(client, false);
582 stop();
583 }
584 }
585
586 AudioParameter param;
587 param.add(String8("closing"), String8("true"));
588 mClientInterface->setParameters(mIoHandle, param.toString());
589
590 mClientInterface->closeOutput(mIoHandle);
591
592 LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
593 __FUNCTION__, mProfile->curOpenCount);
594 mProfile->curOpenCount--;
595 mIoHandle = AUDIO_IO_HANDLE_NONE;
596 }
597 }
598
openDuplicating(const sp<SwAudioOutputDescriptor> & output1,const sp<SwAudioOutputDescriptor> & output2,audio_io_handle_t * ioHandle)599 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
600 const sp<SwAudioOutputDescriptor>& output2,
601 audio_io_handle_t *ioHandle)
602 {
603 // open a duplicating output thread for the new output and the primary output
604 // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
605 // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
606 *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
607 if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
608 return INVALID_OPERATION;
609 }
610
611 mId = PolicyAudioPort::getNextUniqueId();
612 mIoHandle = *ioHandle;
613 mOutput1 = output1;
614 mOutput2 = output2;
615 mSamplingRate = output2->mSamplingRate;
616 mFormat = output2->mFormat;
617 mChannelMask = output2->mChannelMask;
618 mLatency = output2->mLatency;
619
620 return NO_ERROR;
621 }
622
623 // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor(const sp<SourceClientDescriptor> & source,AudioPolicyClientInterface * clientInterface)624 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
625 AudioPolicyClientInterface *clientInterface)
626 : AudioOutputDescriptor(source->srcDevice(), clientInterface),
627 mSource(source)
628 {
629 }
630
dump(String8 * dst) const631 void HwAudioOutputDescriptor::dump(String8 *dst) const
632 {
633 AudioOutputDescriptor::dump(dst);
634 dst->append("Source:\n");
635 mSource->dump(dst, 0, 0);
636 }
637
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const638 void HwAudioOutputDescriptor::toAudioPortConfig(
639 struct audio_port_config *dstConfig,
640 const struct audio_port_config *srcConfig) const
641 {
642 mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
643 }
644
toAudioPort(struct audio_port * port) const645 void HwAudioOutputDescriptor::toAudioPort(
646 struct audio_port *port) const
647 {
648 mSource->srcDevice()->toAudioPort(port);
649 }
650
651
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector & streams,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)652 bool HwAudioOutputDescriptor::setVolume(float volumeDb,
653 VolumeSource volumeSource, const StreamTypeVector &streams,
654 const DeviceTypeSet& deviceTypes,
655 uint32_t delayMs,
656 bool force)
657 {
658 bool changed = AudioOutputDescriptor::setVolume(
659 volumeDb, volumeSource, streams, deviceTypes, delayMs, force);
660
661 if (changed) {
662 // TODO: use gain controller on source device if any to adjust volume
663 }
664 return changed;
665 }
666
667 // SwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const668 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
669 {
670 nsecs_t sysTime = systemTime();
671 for (size_t i = 0; i < this->size(); i++) {
672 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
673 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
674 return true;
675 }
676 }
677 return false;
678 }
679
isActiveLocally(VolumeSource volumeSource,uint32_t inPastMs) const680 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
681 {
682 nsecs_t sysTime = systemTime();
683 for (size_t i = 0; i < this->size(); i++) {
684 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
685 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
686 && (!(outputDesc->devices()
687 .containsDeviceAmongTypes(getAllOutRemoteDevices())))) {
688 return true;
689 }
690 }
691 return false;
692 }
693
isActiveRemotely(VolumeSource volumeSource,uint32_t inPastMs) const694 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
695 {
696 nsecs_t sysTime = systemTime();
697 for (size_t i = 0; i < size(); i++) {
698 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
699 if (outputDesc->devices().containsDeviceAmongTypes(getAllOutRemoteDevices()) &&
700 outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
701 // do not consider re routing (when the output is going to a dynamic policy)
702 // as "remote playback"
703 if (outputDesc->mPolicyMix == NULL) {
704 return true;
705 }
706 }
707 }
708 return false;
709 }
710
isStrategyActiveOnSameModule(product_strategy_t ps,const sp<SwAudioOutputDescriptor> & desc,uint32_t inPastMs,nsecs_t sysTime) const711 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
712 const sp<SwAudioOutputDescriptor>& desc,
713 uint32_t inPastMs, nsecs_t sysTime) const
714 {
715 for (size_t i = 0; i < size(); i++) {
716 const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
717 if (desc->sharesHwModuleWith(otherDesc) &&
718 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
719 return true;
720 }
721 }
722 return false;
723 }
724
getA2dpOutput() const725 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
726 {
727 for (size_t i = 0; i < size(); i++) {
728 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
729 if (!outputDesc->isDuplicated() &&
730 outputDesc->devices().containsDeviceAmongTypes(getAudioDeviceOutAllA2dpSet()) &&
731 outputDesc->devicesSupportEncodedFormats(getAudioDeviceOutAllA2dpSet())) {
732 return this->keyAt(i);
733 }
734 }
735 return 0;
736 }
737
isA2dpOffloadedOnPrimary() const738 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
739 {
740 sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
741
742 if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
743 && (primaryOutput->mProfile->getModule() != NULL)) {
744 sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
745
746 for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
747 if (outputProfile->supportsDeviceTypes(getAudioDeviceOutAllA2dpSet())) {
748 return true;
749 }
750 }
751 }
752 return false;
753 }
754
isA2dpSupported() const755 bool SwAudioOutputCollection::isA2dpSupported() const
756 {
757 return (isA2dpOffloadedOnPrimary() || (getA2dpOutput() != 0));
758 }
759
getPrimaryOutput() const760 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
761 {
762 for (size_t i = 0; i < size(); i++) {
763 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
764 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
765 return outputDesc;
766 }
767 }
768 return NULL;
769 }
770
getOutputFromId(audio_port_handle_t id) const771 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
772 {
773 for (size_t i = 0; i < size(); i++) {
774 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
775 if (outputDesc->getId() == id) {
776 return outputDesc;
777 }
778 }
779 return NULL;
780 }
781
getOutputForClient(audio_port_handle_t portId)782 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
783 {
784 for (size_t i = 0; i < size(); i++) {
785 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
786 if (outputDesc->getClient(portId) != nullptr) {
787 return outputDesc;
788 }
789 }
790 return 0;
791 }
792
clearSessionRoutesForDevice(const sp<DeviceDescriptor> & disconnectedDevice)793 void SwAudioOutputCollection::clearSessionRoutesForDevice(
794 const sp<DeviceDescriptor> &disconnectedDevice)
795 {
796 for (size_t i = 0; i < size(); i++) {
797 sp<AudioOutputDescriptor> outputDesc = valueAt(i);
798 for (const auto& client : outputDesc->getClientIterable()) {
799 if (client->preferredDeviceId() == disconnectedDevice->getId()) {
800 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
801 }
802 }
803 }
804 }
805
dump(String8 * dst) const806 void SwAudioOutputCollection::dump(String8 *dst) const
807 {
808 dst->append("\nOutputs dump:\n");
809 for (size_t i = 0; i < size(); i++) {
810 dst->appendFormat("- Output %d dump:\n", keyAt(i));
811 valueAt(i)->dump(dst);
812 }
813 }
814
815 // HwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const816 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
817 {
818 nsecs_t sysTime = systemTime();
819 for (size_t i = 0; i < this->size(); i++) {
820 const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
821 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
822 return true;
823 }
824 }
825 return false;
826 }
827
dump(String8 * dst) const828 void HwAudioOutputCollection::dump(String8 *dst) const
829 {
830 dst->append("\nOutputs dump:\n");
831 for (size_t i = 0; i < size(); i++) {
832 dst->appendFormat("- Output %d dump:\n", keyAt(i));
833 valueAt(i)->dump(dst);
834 }
835 }
836
837 }; //namespace android
838