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
isClientActive(const sp<TrackClientDescriptor> & client)126 bool AudioOutputDescriptor::isClientActive(const sp<TrackClientDescriptor>& client)
127 {
128 return client != nullptr &&
129 std::find(begin(mActiveClients), end(mActiveClients), client) != end(mActiveClients);
130 }
131
isActive(VolumeSource vs,uint32_t inPastMs,nsecs_t sysTime) const132 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
133 {
134 return (vs == VOLUME_SOURCE_NONE) ?
135 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
136 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
137 }
138
isActive(uint32_t inPastMs) const139 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
140 {
141 nsecs_t sysTime = 0;
142 if (inPastMs != 0) {
143 sysTime = systemTime();
144 }
145 for (const auto &iter : mVolumeActivities) {
146 if (iter.second.isActive(inPastMs, sysTime)) {
147 return true;
148 }
149 }
150 return false;
151 }
152
isFixedVolume(const DeviceTypeSet & deviceTypes __unused)153 bool AudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes __unused)
154 {
155 return false;
156 }
157
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector &,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)158 bool AudioOutputDescriptor::setVolume(float volumeDb,
159 VolumeSource volumeSource,
160 const StreamTypeVector &/*streams*/,
161 const DeviceTypeSet& deviceTypes,
162 uint32_t delayMs,
163 bool force)
164 {
165
166 if (!supportedDevices().containsDeviceAmongTypes(deviceTypes)) {
167 ALOGV("%s output ID %d unsupported device %s",
168 __func__, getId(), toString(deviceTypes).c_str());
169 return false;
170 }
171 // We actually change the volume if:
172 // - the float value returned by computeVolume() changed
173 // - the force flag is set
174 if (volumeDb != getCurVolume(volumeSource) || force) {
175 ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
176 setCurVolume(volumeSource, volumeDb);
177 return true;
178 }
179 return false;
180 }
181
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)182 status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
183 audio_port_config *backupConfig)
184 {
185 struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
186 status_t status = NO_ERROR;
187
188 toAudioPortConfig(&localBackupConfig);
189 if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
190 AudioPortConfig::applyAudioPortConfig(config, backupConfig);
191 applyPolicyAudioPortConfig(config);
192 }
193
194 if (backupConfig != NULL) {
195 *backupConfig = localBackupConfig;
196 }
197 return status;
198 }
199
200
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const201 void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
202 const struct audio_port_config *srcConfig) const
203 {
204 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
205 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
206 if (srcConfig != NULL) {
207 dstConfig->config_mask |= srcConfig->config_mask;
208 }
209 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
210 toPolicyAudioPortConfig(dstConfig, srcConfig);
211
212 dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
213 dstConfig->type = AUDIO_PORT_TYPE_MIX;
214 dstConfig->ext.mix.hw_module = getModuleHandle();
215 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
216 }
217
toAudioPort(struct audio_port_v7 * port) const218 void AudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
219 {
220 // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
221 mPolicyAudioPort->asAudioPort()->toAudioPort(port);
222 port->id = mId;
223 port->ext.mix.hw_module = getModuleHandle();
224 }
225
clientsList(bool activeOnly,product_strategy_t strategy,bool preferredDeviceOnly) const226 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
227 bool preferredDeviceOnly) const
228 {
229 TrackClientVector clients;
230 for (const auto &client : getClientIterable()) {
231 if ((!activeOnly || client->active())
232 && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
233 && (!preferredDeviceOnly ||
234 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
235 clients.push_back(client);
236 }
237 }
238 return clients;
239 }
240
isAnyActive(VolumeSource volumeSourceToIgnore) const241 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
242 {
243 return std::find_if(begin(mActiveClients), end(mActiveClients),
244 [&volumeSourceToIgnore](const auto &client) {
245 return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
246 }
247
dump(String8 * dst) const248 void AudioOutputDescriptor::dump(String8 *dst) const
249 {
250 dst->appendFormat(" ID: %d\n", mId);
251 dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
252 dst->appendFormat(" Format: %08x\n", mFormat);
253 dst->appendFormat(" Channels: %08x\n", mChannelMask);
254 dst->appendFormat(" Devices: %s\n", devices().toString(true /*includeSensitiveInfo*/).c_str());
255 dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
256 for (const auto &iter : mRoutingActivities) {
257 dst->appendFormat(" Product Strategy id: %d", iter.first);
258 iter.second.dump(dst, 4);
259 }
260 for (const auto &iter : mVolumeActivities) {
261 dst->appendFormat(" Volume Activities id: %d", iter.first);
262 iter.second.dump(dst, 4);
263 }
264 dst->append(" AudioTrack Clients:\n");
265 ClientMapHandler<TrackClientDescriptor>::dump(dst);
266 dst->append("\n");
267 if (!mActiveClients.empty()) {
268 dst->append(" AudioTrack active (stream) clients:\n");
269 size_t index = 0;
270 for (const auto& client : mActiveClients) {
271 client->dump(dst, 2, index++);
272 }
273 dst->append(" \n");
274 }
275 }
276
log(const char * indent)277 void AudioOutputDescriptor::log(const char* indent)
278 {
279 ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
280 indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
281 }
282
283 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)284 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
285 AudioPolicyClientInterface *clientInterface)
286 : AudioOutputDescriptor(profile, clientInterface),
287 mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
288 mFlags((audio_output_flags_t)0),
289 mOutput1(0), mOutput2(0), mDirectOpenCount(0),
290 mDirectClientSession(AUDIO_SESSION_NONE)
291 {
292 if (profile != NULL) {
293 mFlags = (audio_output_flags_t)profile->getFlags();
294 }
295 }
296
dump(String8 * dst) const297 void SwAudioOutputDescriptor::dump(String8 *dst) const
298 {
299 dst->appendFormat(" Latency: %d\n", mLatency);
300 dst->appendFormat(" Flags %08x\n", mFlags);
301 AudioOutputDescriptor::dump(dst);
302 }
303
devices() const304 DeviceVector SwAudioOutputDescriptor::devices() const
305 {
306 if (isDuplicated()) {
307 DeviceVector devices = mOutput1->devices();
308 devices.merge(mOutput2->devices());
309 return devices;
310 }
311 return mDevices;
312 }
313
sharesHwModuleWith(const sp<SwAudioOutputDescriptor> & outputDesc)314 bool SwAudioOutputDescriptor::sharesHwModuleWith(
315 const sp<SwAudioOutputDescriptor>& outputDesc)
316 {
317 if (isDuplicated()) {
318 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
319 } else if (outputDesc->isDuplicated()){
320 return sharesHwModuleWith(outputDesc->subOutput1()) ||
321 sharesHwModuleWith(outputDesc->subOutput2());
322 } else {
323 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
324 }
325 }
326
supportedDevices() const327 DeviceVector SwAudioOutputDescriptor::supportedDevices() const
328 {
329 if (isDuplicated()) {
330 DeviceVector supportedDevices = mOutput1->supportedDevices();
331 supportedDevices.merge(mOutput2->supportedDevices());
332 return supportedDevices;
333 }
334 return mProfile->getSupportedDevices();
335 }
336
supportsDevice(const sp<DeviceDescriptor> & device) const337 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
338 {
339 return supportedDevices().contains(device);
340 }
341
supportsAllDevices(const DeviceVector & devices) const342 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
343 {
344 return supportedDevices().containsAllDevices(devices);
345 }
346
supportsDevicesForPlayback(const DeviceVector & devices) const347 bool SwAudioOutputDescriptor::supportsDevicesForPlayback(const DeviceVector &devices) const
348 {
349 // No considering duplicated output
350 // TODO: need to verify if the profile supports the devices combo for playback.
351 return !isDuplicated() && supportsAllDevices(devices);
352 }
353
filterSupportedDevices(const DeviceVector & devices) const354 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
355 {
356 DeviceVector filteredDevices = supportedDevices();
357 return filteredDevices.filter(devices);
358 }
359
devicesSupportEncodedFormats(const DeviceTypeSet & deviceTypes)360 bool SwAudioOutputDescriptor::devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes)
361 {
362 if (isDuplicated()) {
363 return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
364 || mOutput2->devicesSupportEncodedFormats(deviceTypes));
365 } else {
366 return mProfile->devicesSupportEncodedFormats(deviceTypes);
367 }
368 }
369
containsSingleDeviceSupportingEncodedFormats(const sp<DeviceDescriptor> & device) const370 bool SwAudioOutputDescriptor::containsSingleDeviceSupportingEncodedFormats(
371 const sp<DeviceDescriptor>& device) const
372 {
373 if (isDuplicated()) {
374 return (mOutput1->containsSingleDeviceSupportingEncodedFormats(device) &&
375 mOutput2->containsSingleDeviceSupportingEncodedFormats(device));
376 }
377 return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
378 }
379
latency()380 uint32_t SwAudioOutputDescriptor::latency()
381 {
382 if (isDuplicated()) {
383 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
384 } else {
385 return mLatency;
386 }
387 }
388
setClientActive(const sp<TrackClientDescriptor> & client,bool active)389 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
390 {
391 // forward usage count change to attached outputs
392 if (isDuplicated()) {
393 mOutput1->setClientActive(client, active);
394 mOutput2->setClientActive(client, active);
395 }
396 AudioOutputDescriptor::setClientActive(client, active);
397 }
398
isFixedVolume(const DeviceTypeSet & deviceTypes)399 bool SwAudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes)
400 {
401 // unit gain if rerouting to external policy
402 if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
403 if (mPolicyMix != NULL) {
404 ALOGV("max gain when rerouting for output=%d", mIoHandle);
405 return true;
406 }
407 }
408 if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
409 ALOGV("max gain when output device is telephony tx");
410 return true;
411 }
412 return false;
413 }
414
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const415 void SwAudioOutputDescriptor::toAudioPortConfig(
416 struct audio_port_config *dstConfig,
417 const struct audio_port_config *srcConfig) const
418 {
419
420 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
421 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
422
423 dstConfig->ext.mix.handle = mIoHandle;
424 }
425
toAudioPort(struct audio_port_v7 * port) const426 void SwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
427 {
428 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
429
430 AudioOutputDescriptor::toAudioPort(port);
431
432 toAudioPortConfig(&port->active_config);
433 port->ext.mix.handle = mIoHandle;
434 port->ext.mix.latency_class =
435 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
436 }
437
setVolume(float volumeDb,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)438 bool SwAudioOutputDescriptor::setVolume(float volumeDb,
439 VolumeSource vs, const StreamTypeVector &streamTypes,
440 const DeviceTypeSet& deviceTypes,
441 uint32_t delayMs,
442 bool force)
443 {
444 StreamTypeVector streams = streamTypes;
445 if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, deviceTypes, delayMs, force)) {
446 return false;
447 }
448 if (streams.empty()) {
449 streams.push_back(AUDIO_STREAM_MUSIC);
450 }
451 for (const auto& devicePort : devices()) {
452 // APM loops on all group, so filter on active group to set the port gain,
453 // let the other groups set the stream volume as per legacy
454 // TODO: Pass in the device address and check against it.
455 if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
456 devicePort->hasGainController(true) && isActive(vs)) {
457 ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
458 // @todo: here we might be in trouble if the SwOutput has several active clients with
459 // different Volume Source (or if we allow several curves within same volume group)
460 //
461 // @todo: default stream volume to max (0) when using HW Port gain?
462 float volumeAmpl = Volume::DbToAmpl(0);
463 for (const auto &stream : streams) {
464 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
465 }
466
467 AudioGains gains = devicePort->getGains();
468 int gainMinValueInMb = gains[0]->getMinValueInMb();
469 int gainMaxValueInMb = gains[0]->getMaxValueInMb();
470 int gainStepValueInMb = gains[0]->getStepValueInMb();
471 int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
472 gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
473
474 audio_port_config config = {};
475 devicePort->toAudioPortConfig(&config);
476 config.config_mask = AUDIO_PORT_CONFIG_GAIN;
477 config.gain.values[0] = gainValueMb;
478 return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
479 }
480 }
481 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
482 float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
483 if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
484 mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
485 }
486 for (const auto &stream : streams) {
487 ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
488 mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
489 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
490 }
491 return true;
492 }
493
open(const audio_config_t * config,const DeviceVector & devices,audio_stream_type_t stream,audio_output_flags_t flags,audio_io_handle_t * output)494 status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
495 const DeviceVector &devices,
496 audio_stream_type_t stream,
497 audio_output_flags_t flags,
498 audio_io_handle_t *output)
499 {
500 mDevices = devices;
501 sp<DeviceDescriptor> device = devices.getDeviceForOpening();
502 LOG_ALWAYS_FATAL_IF(device == nullptr,
503 "%s failed to get device descriptor for opening "
504 "with the requested devices, all device types: %s",
505 __func__, dumpDeviceTypes(devices.types()).c_str());
506
507 audio_config_t lConfig;
508 if (config == nullptr) {
509 lConfig = AUDIO_CONFIG_INITIALIZER;
510 lConfig.sample_rate = mSamplingRate;
511 lConfig.channel_mask = mChannelMask;
512 lConfig.format = mFormat;
513 } else {
514 lConfig = *config;
515 }
516
517 // if the selected profile is offloaded and no offload info was specified,
518 // create a default one
519 if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
520 lConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
521 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
522 lConfig.offload_info = AUDIO_INFO_INITIALIZER;
523 lConfig.offload_info.sample_rate = lConfig.sample_rate;
524 lConfig.offload_info.channel_mask = lConfig.channel_mask;
525 lConfig.offload_info.format = lConfig.format;
526 lConfig.offload_info.stream_type = stream;
527 lConfig.offload_info.duration_us = -1;
528 lConfig.offload_info.has_video = true; // conservative
529 lConfig.offload_info.is_streaming = true; // likely
530 lConfig.offload_info.encapsulation_mode = lConfig.offload_info.encapsulation_mode;
531 lConfig.offload_info.content_id = lConfig.offload_info.content_id;
532 lConfig.offload_info.sync_id = lConfig.offload_info.sync_id;
533 }
534
535 mFlags = (audio_output_flags_t)(mFlags | flags);
536
537 ALOGV("opening output for device %s profile %p name %s",
538 mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str());
539
540 status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
541 output,
542 &lConfig,
543 device,
544 &mLatency,
545 mFlags);
546
547 if (status == NO_ERROR) {
548 LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
549 "%s openOutput returned output handle %d for device %s, "
550 "selected device %s for opening",
551 __FUNCTION__, *output, devices.toString().c_str(),
552 device->toString().c_str());
553 mSamplingRate = lConfig.sample_rate;
554 mChannelMask = lConfig.channel_mask;
555 mFormat = lConfig.format;
556 mId = PolicyAudioPort::getNextUniqueId();
557 mIoHandle = *output;
558 mProfile->curOpenCount++;
559 }
560
561 return status;
562 }
563
start()564 status_t SwAudioOutputDescriptor::start()
565 {
566 if (isDuplicated()) {
567 status_t status = mOutput1->start();
568 if (status != NO_ERROR) {
569 return status;
570 }
571 status = mOutput2->start();
572 if (status != NO_ERROR) {
573 mOutput1->stop();
574 return status;
575 }
576 return NO_ERROR;
577 }
578 if (!isActive()) {
579 if (!mProfile->canStartNewIo()) {
580 return INVALID_OPERATION;
581 }
582 mProfile->curActiveCount++;
583 }
584 return NO_ERROR;
585 }
586
stop()587 void SwAudioOutputDescriptor::stop()
588 {
589 if (isDuplicated()) {
590 mOutput1->stop();
591 mOutput2->stop();
592 return;
593 }
594
595 if (!isActive()) {
596 LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
597 "%s invalid profile active count %u",
598 __func__, mProfile->curActiveCount);
599 mProfile->curActiveCount--;
600 }
601 }
602
close()603 void SwAudioOutputDescriptor::close()
604 {
605 if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
606 // clean up active clients if any (can happen if close() is called to force
607 // clients to reconnect
608 for (const auto &client : getClientIterable()) {
609 if (client->active()) {
610 ALOGW("%s client with port ID %d still active on output %d",
611 __func__, client->portId(), mId);
612 setClientActive(client, false);
613 stop();
614 }
615 }
616
617 AudioParameter param;
618 param.add(String8("closing"), String8("true"));
619 mClientInterface->setParameters(mIoHandle, param.toString());
620
621 mClientInterface->closeOutput(mIoHandle);
622
623 LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
624 __FUNCTION__, mProfile->curOpenCount);
625 mProfile->curOpenCount--;
626 mIoHandle = AUDIO_IO_HANDLE_NONE;
627 }
628 }
629
openDuplicating(const sp<SwAudioOutputDescriptor> & output1,const sp<SwAudioOutputDescriptor> & output2,audio_io_handle_t * ioHandle)630 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
631 const sp<SwAudioOutputDescriptor>& output2,
632 audio_io_handle_t *ioHandle)
633 {
634 // open a duplicating output thread for the new output and the primary output
635 // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
636 // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
637 *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
638 if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
639 return INVALID_OPERATION;
640 }
641
642 mId = PolicyAudioPort::getNextUniqueId();
643 mIoHandle = *ioHandle;
644 mOutput1 = output1;
645 mOutput2 = output2;
646 mSamplingRate = output2->mSamplingRate;
647 mFormat = output2->mFormat;
648 mChannelMask = output2->mChannelMask;
649 mLatency = output2->mLatency;
650
651 return NO_ERROR;
652 }
653
654 // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor(const sp<SourceClientDescriptor> & source,AudioPolicyClientInterface * clientInterface)655 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
656 AudioPolicyClientInterface *clientInterface)
657 : AudioOutputDescriptor(source->srcDevice(), clientInterface),
658 mSource(source)
659 {
660 }
661
dump(String8 * dst) const662 void HwAudioOutputDescriptor::dump(String8 *dst) const
663 {
664 AudioOutputDescriptor::dump(dst);
665 dst->append("Source:\n");
666 mSource->dump(dst, 0, 0);
667 }
668
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const669 void HwAudioOutputDescriptor::toAudioPortConfig(
670 struct audio_port_config *dstConfig,
671 const struct audio_port_config *srcConfig) const
672 {
673 mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
674 }
675
toAudioPort(struct audio_port_v7 * port) const676 void HwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
677 {
678 mSource->srcDevice()->toAudioPort(port);
679 }
680
681
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector & streams,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)682 bool HwAudioOutputDescriptor::setVolume(float volumeDb,
683 VolumeSource volumeSource, const StreamTypeVector &streams,
684 const DeviceTypeSet& deviceTypes,
685 uint32_t delayMs,
686 bool force)
687 {
688 bool changed = AudioOutputDescriptor::setVolume(
689 volumeDb, volumeSource, streams, deviceTypes, delayMs, force);
690
691 if (changed) {
692 // TODO: use gain controller on source device if any to adjust volume
693 }
694 return changed;
695 }
696
697 // SwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const698 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
699 {
700 nsecs_t sysTime = systemTime();
701 for (size_t i = 0; i < this->size(); i++) {
702 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
703 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
704 return true;
705 }
706 }
707 return false;
708 }
709
isActiveLocally(VolumeSource volumeSource,uint32_t inPastMs) const710 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
711 {
712 nsecs_t sysTime = systemTime();
713 for (size_t i = 0; i < this->size(); i++) {
714 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
715 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
716 && (!(outputDesc->devices()
717 .containsDeviceAmongTypes(getAllOutRemoteDevices())
718 || outputDesc->devices()
719 .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)))) {
720 return true;
721 }
722 }
723 return false;
724 }
725
isActiveRemotely(VolumeSource volumeSource,uint32_t inPastMs) const726 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
727 {
728 nsecs_t sysTime = systemTime();
729 for (size_t i = 0; i < size(); i++) {
730 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
731 if (outputDesc->devices().containsDeviceAmongTypes(getAllOutRemoteDevices()) &&
732 outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
733 // do not consider re routing (when the output is going to a dynamic policy)
734 // as "remote playback"
735 if (outputDesc->mPolicyMix == NULL) {
736 return true;
737 }
738 }
739 }
740 return false;
741 }
742
isStrategyActiveOnSameModule(product_strategy_t ps,const sp<SwAudioOutputDescriptor> & desc,uint32_t inPastMs,nsecs_t sysTime) const743 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
744 const sp<SwAudioOutputDescriptor>& desc,
745 uint32_t inPastMs, nsecs_t sysTime) const
746 {
747 for (size_t i = 0; i < size(); i++) {
748 const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
749 if (desc->sharesHwModuleWith(otherDesc) &&
750 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
751 if (desc == otherDesc
752 || !otherDesc->devices()
753 .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
754 return true;
755 }
756 }
757 }
758 return false;
759 }
760
getA2dpOutput() const761 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
762 {
763 for (size_t i = 0; i < size(); i++) {
764 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
765 if (!outputDesc->isDuplicated() &&
766 outputDesc->devices().containsDeviceAmongTypes(getAudioDeviceOutAllA2dpSet()) &&
767 outputDesc->devicesSupportEncodedFormats(getAudioDeviceOutAllA2dpSet())) {
768 return this->keyAt(i);
769 }
770 }
771 return 0;
772 }
773
isA2dpOffloadedOnPrimary() const774 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
775 {
776 sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
777
778 if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
779 && (primaryOutput->mProfile->getModule() != NULL)) {
780 sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
781
782 for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
783 if (outputProfile->supportsDeviceTypes(getAudioDeviceOutAllA2dpSet())) {
784 return true;
785 }
786 }
787 }
788 return false;
789 }
790
getPrimaryOutput() const791 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
792 {
793 for (size_t i = 0; i < size(); i++) {
794 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
795 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
796 return outputDesc;
797 }
798 }
799 return NULL;
800 }
801
getOutputFromId(audio_port_handle_t id) const802 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
803 {
804 for (size_t i = 0; i < size(); i++) {
805 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
806 if (outputDesc->getId() == id) {
807 return outputDesc;
808 }
809 }
810 return NULL;
811 }
812
getOutputForClient(audio_port_handle_t portId)813 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
814 {
815 for (size_t i = 0; i < size(); i++) {
816 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
817 if (outputDesc->getClient(portId) != nullptr) {
818 return outputDesc;
819 }
820 }
821 return 0;
822 }
823
clearSessionRoutesForDevice(const sp<DeviceDescriptor> & disconnectedDevice)824 void SwAudioOutputCollection::clearSessionRoutesForDevice(
825 const sp<DeviceDescriptor> &disconnectedDevice)
826 {
827 for (size_t i = 0; i < size(); i++) {
828 sp<AudioOutputDescriptor> outputDesc = valueAt(i);
829 for (const auto& client : outputDesc->getClientIterable()) {
830 if (client->preferredDeviceId() == disconnectedDevice->getId()) {
831 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
832 }
833 }
834 }
835 }
836
dump(String8 * dst) const837 void SwAudioOutputCollection::dump(String8 *dst) const
838 {
839 dst->append("\nOutputs dump:\n");
840 for (size_t i = 0; i < size(); i++) {
841 dst->appendFormat("- Output %d dump:\n", keyAt(i));
842 valueAt(i)->dump(dst);
843 }
844 }
845
846 // HwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const847 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
848 {
849 nsecs_t sysTime = systemTime();
850 for (size_t i = 0; i < this->size(); i++) {
851 const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
852 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
853 return true;
854 }
855 }
856 return false;
857 }
858
dump(String8 * dst) const859 void HwAudioOutputCollection::dump(String8 *dst) const
860 {
861 dst->append("\nOutputs dump:\n");
862 for (size_t i = 0; i < size(); i++) {
863 dst->appendFormat("- Output %d dump:\n", keyAt(i));
864 valueAt(i)->dump(dst);
865 }
866 }
867
868 }; //namespace android
869