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 "IOProfile.h"
23 #include "AudioGain.h"
24 #include "Volume.h"
25 #include "HwModule.h"
26 #include <media/AudioParameter.h>
27 #include <media/AudioPolicy.h>
28
29 // A device mask for all audio output devices that are considered "remote" when evaluating
30 // active output devices in isStreamActiveRemotely()
31 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX
32
33 namespace android {
34
AudioOutputDescriptor(const sp<AudioPort> & port,AudioPolicyClientInterface * clientInterface)35 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
36 AudioPolicyClientInterface *clientInterface)
37 : mPort(port), mDevice(AUDIO_DEVICE_NONE),
38 mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
39 {
40 // clear usage count for all stream types
41 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
42 mRefCount[i] = 0;
43 mCurVolume[i] = -1.0;
44 mMuteCount[i] = 0;
45 mStopTime[i] = 0;
46 }
47 for (int i = 0; i < NUM_STRATEGIES; i++) {
48 mStrategyMutedByDevice[i] = false;
49 }
50 if (mPort.get() != nullptr) {
51 mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
52 if (mPort->mGains.size() > 0) {
53 mPort->mGains[0]->getDefaultConfig(&mGain);
54 }
55 }
56 }
57
getModuleHandle() const58 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
59 {
60 return mPort.get() != nullptr ? mPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
61 }
62
getId() const63 audio_port_handle_t AudioOutputDescriptor::getId() const
64 {
65 return mId;
66 }
67
device() const68 audio_devices_t AudioOutputDescriptor::device() const
69 {
70 return mDevice;
71 }
72
supportedDevices()73 audio_devices_t AudioOutputDescriptor::supportedDevices()
74 {
75 return mDevice;
76 }
77
sharesHwModuleWith(const sp<AudioOutputDescriptor> & outputDesc)78 bool AudioOutputDescriptor::sharesHwModuleWith(
79 const sp<AudioOutputDescriptor>& outputDesc)
80 {
81 if (outputDesc->isDuplicated()) {
82 return sharesHwModuleWith(outputDesc->subOutput1()) ||
83 sharesHwModuleWith(outputDesc->subOutput2());
84 } else {
85 return hasSameHwModuleAs(outputDesc);
86 }
87 }
88
changeRefCount(audio_stream_type_t stream,int delta)89 void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
90 int delta)
91 {
92 if ((delta + (int)mRefCount[stream]) < 0) {
93 ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
94 delta, stream, mRefCount[stream]);
95 mRefCount[stream] = 0;
96 return;
97 }
98 mRefCount[stream] += delta;
99 ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
100 }
101
isActive(uint32_t inPastMs) const102 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
103 {
104 nsecs_t sysTime = 0;
105 if (inPastMs != 0) {
106 sysTime = systemTime();
107 }
108 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
109 if (i == AUDIO_STREAM_PATCH) {
110 continue;
111 }
112 if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
113 return true;
114 }
115 }
116 return false;
117 }
118
isStreamActive(audio_stream_type_t stream,uint32_t inPastMs,nsecs_t sysTime) const119 bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
120 uint32_t inPastMs,
121 nsecs_t sysTime) const
122 {
123 if (mRefCount[stream] != 0) {
124 return true;
125 }
126 if (inPastMs == 0) {
127 return false;
128 }
129 if (sysTime == 0) {
130 sysTime = systemTime();
131 }
132 if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
133 return true;
134 }
135 return false;
136 }
137
138
isFixedVolume(audio_devices_t device __unused)139 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
140 {
141 return false;
142 }
143
setVolume(float volume,audio_stream_type_t stream,audio_devices_t device __unused,uint32_t delayMs,bool force)144 bool AudioOutputDescriptor::setVolume(float volume,
145 audio_stream_type_t stream,
146 audio_devices_t device __unused,
147 uint32_t delayMs,
148 bool force)
149 {
150 // We actually change the volume if:
151 // - the float value returned by computeVolume() changed
152 // - the force flag is set
153 if (volume != mCurVolume[stream] || force) {
154 ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
155 mCurVolume[stream] = volume;
156 return true;
157 }
158 return false;
159 }
160
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const161 void AudioOutputDescriptor::toAudioPortConfig(
162 struct audio_port_config *dstConfig,
163 const struct audio_port_config *srcConfig) const
164 {
165 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
166 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
167 if (srcConfig != NULL) {
168 dstConfig->config_mask |= srcConfig->config_mask;
169 }
170 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
171
172 dstConfig->id = mId;
173 dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
174 dstConfig->type = AUDIO_PORT_TYPE_MIX;
175 dstConfig->ext.mix.hw_module = getModuleHandle();
176 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
177 }
178
toAudioPort(struct audio_port * port) const179 void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const
180 {
181 // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
182 mPort->toAudioPort(port);
183 port->id = mId;
184 port->ext.mix.hw_module = getModuleHandle();
185 }
186
dump(int fd)187 status_t AudioOutputDescriptor::dump(int fd)
188 {
189 const size_t SIZE = 256;
190 char buffer[SIZE];
191 String8 result;
192
193 snprintf(buffer, SIZE, " ID: %d\n", mId);
194 result.append(buffer);
195 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
196 result.append(buffer);
197 snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
198 result.append(buffer);
199 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
200 result.append(buffer);
201 snprintf(buffer, SIZE, " Devices %08x\n", device());
202 result.append(buffer);
203 snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
204 result.append(buffer);
205 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
206 snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n",
207 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
208 result.append(buffer);
209 }
210 write(fd, result.string(), result.size());
211
212 return NO_ERROR;
213 }
214
log(const char * indent)215 void AudioOutputDescriptor::log(const char* indent)
216 {
217 ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
218 indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
219 }
220
221 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)222 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
223 AudioPolicyClientInterface *clientInterface)
224 : AudioOutputDescriptor(profile, clientInterface),
225 mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
226 mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
227 mOutput1(0), mOutput2(0), mDirectOpenCount(0),
228 mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0)
229 {
230 if (profile != NULL) {
231 mFlags = (audio_output_flags_t)profile->getFlags();
232 }
233 }
234
dump(int fd)235 status_t SwAudioOutputDescriptor::dump(int fd)
236 {
237 const size_t SIZE = 256;
238 char buffer[SIZE];
239 String8 result;
240
241 snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
242 result.append(buffer);
243 snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
244 result.append(buffer);
245 write(fd, result.string(), result.size());
246
247 AudioOutputDescriptor::dump(fd);
248
249 return NO_ERROR;
250 }
251
device() const252 audio_devices_t SwAudioOutputDescriptor::device() const
253 {
254 if (isDuplicated()) {
255 return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
256 } else {
257 return mDevice;
258 }
259 }
260
sharesHwModuleWith(const sp<AudioOutputDescriptor> & outputDesc)261 bool SwAudioOutputDescriptor::sharesHwModuleWith(
262 const sp<AudioOutputDescriptor>& outputDesc)
263 {
264 if (isDuplicated()) {
265 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
266 } else if (outputDesc->isDuplicated()){
267 return sharesHwModuleWith(outputDesc->subOutput1()) ||
268 sharesHwModuleWith(outputDesc->subOutput2());
269 } else {
270 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
271 }
272 }
273
supportedDevices()274 audio_devices_t SwAudioOutputDescriptor::supportedDevices()
275 {
276 if (isDuplicated()) {
277 return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
278 } else {
279 return mProfile->getSupportedDevicesType();
280 }
281 }
282
latency()283 uint32_t SwAudioOutputDescriptor::latency()
284 {
285 if (isDuplicated()) {
286 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
287 } else {
288 return mLatency;
289 }
290 }
291
changeRefCount(audio_stream_type_t stream,int delta)292 void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
293 int delta)
294 {
295 // forward usage count change to attached outputs
296 if (isDuplicated()) {
297 mOutput1->changeRefCount(stream, delta);
298 mOutput2->changeRefCount(stream, delta);
299 }
300 AudioOutputDescriptor::changeRefCount(stream, delta);
301
302 // handle stream-independent ref count
303 uint32_t oldGlobalRefCount = mGlobalRefCount;
304 if ((delta + (int)mGlobalRefCount) < 0) {
305 ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
306 mGlobalRefCount = 0;
307 } else {
308 mGlobalRefCount += delta;
309 }
310 if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
311 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
312 {
313 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
314 MIX_STATE_MIXING);
315 }
316
317 } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
318 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
319 {
320 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
321 MIX_STATE_IDLE);
322 }
323 }
324 }
325
326
isFixedVolume(audio_devices_t device)327 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
328 {
329 // unit gain if rerouting to external policy
330 if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
331 if (mPolicyMix != NULL) {
332 ALOGV("max gain when rerouting for output=%d", mIoHandle);
333 return true;
334 }
335 }
336 if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
337 ALOGV("max gain when output device is telephony tx");
338 return true;
339 }
340 return false;
341 }
342
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const343 void SwAudioOutputDescriptor::toAudioPortConfig(
344 struct audio_port_config *dstConfig,
345 const struct audio_port_config *srcConfig) const
346 {
347
348 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
349 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
350
351 dstConfig->ext.mix.handle = mIoHandle;
352 }
353
toAudioPort(struct audio_port * port) const354 void SwAudioOutputDescriptor::toAudioPort(
355 struct audio_port *port) const
356 {
357 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
358
359 AudioOutputDescriptor::toAudioPort(port);
360
361 toAudioPortConfig(&port->active_config);
362 port->ext.mix.handle = mIoHandle;
363 port->ext.mix.latency_class =
364 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
365 }
366
setVolume(float volume,audio_stream_type_t stream,audio_devices_t device,uint32_t delayMs,bool force)367 bool SwAudioOutputDescriptor::setVolume(float volume,
368 audio_stream_type_t stream,
369 audio_devices_t device,
370 uint32_t delayMs,
371 bool force)
372 {
373 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
374
375 if (changed) {
376 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
377 // enabled
378 float volume = Volume::DbToAmpl(mCurVolume[stream]);
379 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
380 mClientInterface->setStreamVolume(
381 AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs);
382 }
383 mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs);
384 }
385 return changed;
386 }
387
open(const audio_config_t * config,audio_devices_t device,const String8 & address,audio_stream_type_t stream,audio_output_flags_t flags,audio_io_handle_t * output)388 status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
389 audio_devices_t device,
390 const String8& address,
391 audio_stream_type_t stream,
392 audio_output_flags_t flags,
393 audio_io_handle_t *output)
394 {
395 audio_config_t lConfig;
396 if (config == nullptr) {
397 lConfig = AUDIO_CONFIG_INITIALIZER;
398 lConfig.sample_rate = mSamplingRate;
399 lConfig.channel_mask = mChannelMask;
400 lConfig.format = mFormat;
401 } else {
402 lConfig = *config;
403 }
404
405 mDevice = device;
406 // if the selected profile is offloaded and no offload info was specified,
407 // create a default one
408 if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
409 lConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
410 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
411 lConfig.offload_info = AUDIO_INFO_INITIALIZER;
412 lConfig.offload_info.sample_rate = lConfig.sample_rate;
413 lConfig.offload_info.channel_mask = lConfig.channel_mask;
414 lConfig.offload_info.format = lConfig.format;
415 lConfig.offload_info.stream_type = stream;
416 lConfig.offload_info.duration_us = -1;
417 lConfig.offload_info.has_video = true; // conservative
418 lConfig.offload_info.is_streaming = true; // likely
419 }
420
421 mFlags = (audio_output_flags_t)(mFlags | flags);
422
423 ALOGV("opening output for device %08x address %s profile %p name %s",
424 mDevice, address.string(), mProfile.get(), mProfile->getName().string());
425
426 status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
427 output,
428 &lConfig,
429 &mDevice,
430 address,
431 &mLatency,
432 mFlags);
433 LOG_ALWAYS_FATAL_IF(mDevice != device,
434 "%s openOutput returned device %08x when given device %08x",
435 __FUNCTION__, mDevice, device);
436
437 if (status == NO_ERROR) {
438 LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
439 "%s openOutput returned output handle %d for device %08x",
440 __FUNCTION__, *output, device);
441 mSamplingRate = lConfig.sample_rate;
442 mChannelMask = lConfig.channel_mask;
443 mFormat = lConfig.format;
444 mId = AudioPort::getNextUniqueId();
445 mIoHandle = *output;
446 mProfile->curOpenCount++;
447 }
448
449 return status;
450 }
451
start()452 status_t SwAudioOutputDescriptor::start()
453 {
454 if (isDuplicated()) {
455 status_t status = mOutput1->start();
456 if (status != NO_ERROR) {
457 return status;
458 }
459 status = mOutput2->start();
460 if (status != NO_ERROR) {
461 mOutput1->stop();
462 return status;
463 }
464 return NO_ERROR;
465 }
466 if (!isActive()) {
467 if (!mProfile->canStartNewIo()) {
468 return INVALID_OPERATION;
469 }
470 mProfile->curActiveCount++;
471 }
472 return NO_ERROR;
473 }
474
stop()475 void SwAudioOutputDescriptor::stop()
476 {
477 if (isDuplicated()) {
478 mOutput1->stop();
479 mOutput2->stop();
480 return;
481 }
482
483 if (!isActive()) {
484 LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
485 "%s invalid profile active count %u",
486 __func__, mProfile->curActiveCount);
487 mProfile->curActiveCount--;
488 }
489 }
490
close()491 void SwAudioOutputDescriptor::close()
492 {
493 if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
494 AudioParameter param;
495 param.add(String8("closing"), String8("true"));
496 mClientInterface->setParameters(mIoHandle, param.toString());
497
498 mClientInterface->closeOutput(mIoHandle);
499
500 LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
501 __FUNCTION__, mProfile->curOpenCount);
502 // do not call stop() here as stop() is supposed to be called after changeRefCount(-1)
503 // and we don't know how many streams are still active at this time
504 if (isActive()) {
505 mProfile->curActiveCount--;
506 }
507 mProfile->curOpenCount--;
508 mIoHandle = AUDIO_IO_HANDLE_NONE;
509 }
510 }
511
openDuplicating(const sp<SwAudioOutputDescriptor> & output1,const sp<SwAudioOutputDescriptor> & output2,audio_io_handle_t * ioHandle)512 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
513 const sp<SwAudioOutputDescriptor>& output2,
514 audio_io_handle_t *ioHandle)
515 {
516 // open a duplicating output thread for the new output and the primary output
517 // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
518 // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
519 *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
520 if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
521 return INVALID_OPERATION;
522 }
523
524 mId = AudioPort::getNextUniqueId();
525 mIoHandle = *ioHandle;
526 mOutput1 = output1;
527 mOutput2 = output2;
528 mSamplingRate = output2->mSamplingRate;
529 mFormat = output2->mFormat;
530 mChannelMask = output2->mChannelMask;
531 mLatency = output2->mLatency;
532
533 return NO_ERROR;
534 }
535
536 // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor(const sp<AudioSourceDescriptor> & source,AudioPolicyClientInterface * clientInterface)537 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
538 AudioPolicyClientInterface *clientInterface)
539 : AudioOutputDescriptor(source->mDevice, clientInterface),
540 mSource(source)
541 {
542 }
543
dump(int fd)544 status_t HwAudioOutputDescriptor::dump(int fd)
545 {
546 const size_t SIZE = 256;
547 char buffer[SIZE];
548 String8 result;
549
550 AudioOutputDescriptor::dump(fd);
551
552 snprintf(buffer, SIZE, "Source:\n");
553 result.append(buffer);
554 write(fd, result.string(), result.size());
555 mSource->dump(fd);
556
557 return NO_ERROR;
558 }
559
supportedDevices()560 audio_devices_t HwAudioOutputDescriptor::supportedDevices()
561 {
562 return mDevice;
563 }
564
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const565 void HwAudioOutputDescriptor::toAudioPortConfig(
566 struct audio_port_config *dstConfig,
567 const struct audio_port_config *srcConfig) const
568 {
569 mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig);
570 }
571
toAudioPort(struct audio_port * port) const572 void HwAudioOutputDescriptor::toAudioPort(
573 struct audio_port *port) const
574 {
575 mSource->mDevice->toAudioPort(port);
576 }
577
578
setVolume(float volume,audio_stream_type_t stream,audio_devices_t device,uint32_t delayMs,bool force)579 bool HwAudioOutputDescriptor::setVolume(float volume,
580 audio_stream_type_t stream,
581 audio_devices_t device,
582 uint32_t delayMs,
583 bool force)
584 {
585 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
586
587 if (changed) {
588 // TODO: use gain controller on source device if any to adjust volume
589 }
590 return changed;
591 }
592
593 // SwAudioOutputCollection implementation
isStreamActive(audio_stream_type_t stream,uint32_t inPastMs) const594 bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
595 {
596 nsecs_t sysTime = systemTime();
597 for (size_t i = 0; i < this->size(); i++) {
598 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
599 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
600 return true;
601 }
602 }
603 return false;
604 }
605
isStreamActiveLocally(audio_stream_type_t stream,uint32_t inPastMs) const606 bool SwAudioOutputCollection::isStreamActiveLocally(audio_stream_type_t stream, uint32_t inPastMs) const
607 {
608 nsecs_t sysTime = systemTime();
609 for (size_t i = 0; i < this->size(); i++) {
610 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
611 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)
612 && ((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) == 0)) {
613 return true;
614 }
615 }
616 return false;
617 }
618
isStreamActiveRemotely(audio_stream_type_t stream,uint32_t inPastMs) const619 bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
620 uint32_t inPastMs) const
621 {
622 nsecs_t sysTime = systemTime();
623 for (size_t i = 0; i < size(); i++) {
624 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
625 if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
626 outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
627 // do not consider re routing (when the output is going to a dynamic policy)
628 // as "remote playback"
629 if (outputDesc->mPolicyMix == NULL) {
630 return true;
631 }
632 }
633 }
634 return false;
635 }
636
getA2dpOutput() const637 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
638 {
639 for (size_t i = 0; i < size(); i++) {
640 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
641 if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
642 return this->keyAt(i);
643 }
644 }
645 return 0;
646 }
647
isA2dpOffloadedOnPrimary() const648 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
649 {
650 sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
651
652 if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
653 && (primaryOutput->mProfile->mModule != NULL)) {
654 sp<HwModule> primaryHwModule = primaryOutput->mProfile->mModule;
655 Vector <sp<IOProfile>> primaryHwModuleOutputProfiles =
656 primaryHwModule->getOutputProfiles();
657 for (size_t i = 0; i < primaryHwModuleOutputProfiles.size(); i++) {
658 if (primaryHwModuleOutputProfiles[i]->supportDevice(AUDIO_DEVICE_OUT_ALL_A2DP)) {
659 return true;
660 }
661 }
662 }
663 return false;
664 }
665
isA2dpSupported() const666 bool SwAudioOutputCollection::isA2dpSupported() const
667 {
668 return (isA2dpOffloadedOnPrimary() || (getA2dpOutput() != 0));
669 }
670
getPrimaryOutput() const671 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
672 {
673 for (size_t i = 0; i < size(); i++) {
674 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
675 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
676 return outputDesc;
677 }
678 }
679 return NULL;
680 }
681
getOutputFromId(audio_port_handle_t id) const682 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
683 {
684 sp<SwAudioOutputDescriptor> outputDesc = NULL;
685 for (size_t i = 0; i < size(); i++) {
686 outputDesc = valueAt(i);
687 if (outputDesc->getId() == id) {
688 break;
689 }
690 }
691 return outputDesc;
692 }
693
isAnyOutputActive(audio_stream_type_t streamToIgnore) const694 bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
695 {
696 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
697 if (s == (size_t) streamToIgnore) {
698 continue;
699 }
700 for (size_t i = 0; i < size(); i++) {
701 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
702 if (outputDesc->mRefCount[s] != 0) {
703 return true;
704 }
705 }
706 }
707 return false;
708 }
709
getSupportedDevices(audio_io_handle_t handle) const710 audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
711 {
712 sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
713 audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType();
714 return devices;
715 }
716
717
dump(int fd) const718 status_t SwAudioOutputCollection::dump(int fd) const
719 {
720 const size_t SIZE = 256;
721 char buffer[SIZE];
722
723 snprintf(buffer, SIZE, "\nOutputs dump:\n");
724 write(fd, buffer, strlen(buffer));
725 for (size_t i = 0; i < size(); i++) {
726 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
727 write(fd, buffer, strlen(buffer));
728 valueAt(i)->dump(fd);
729 }
730
731 return NO_ERROR;
732 }
733
734 // HwAudioOutputCollection implementation
isStreamActive(audio_stream_type_t stream,uint32_t inPastMs) const735 bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
736 {
737 nsecs_t sysTime = systemTime();
738 for (size_t i = 0; i < this->size(); i++) {
739 const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
740 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
741 return true;
742 }
743 }
744 return false;
745 }
746
isAnyOutputActive(audio_stream_type_t streamToIgnore) const747 bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
748 {
749 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
750 if (s == (size_t) streamToIgnore) {
751 continue;
752 }
753 for (size_t i = 0; i < size(); i++) {
754 const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i);
755 if (outputDesc->mRefCount[s] != 0) {
756 return true;
757 }
758 }
759 }
760 return false;
761 }
762
dump(int fd) const763 status_t HwAudioOutputCollection::dump(int fd) const
764 {
765 const size_t SIZE = 256;
766 char buffer[SIZE];
767
768 snprintf(buffer, SIZE, "\nOutputs dump:\n");
769 write(fd, buffer, strlen(buffer));
770 for (size_t i = 0; i < size(); i++) {
771 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
772 write(fd, buffer, strlen(buffer));
773 valueAt(i)->dump(fd);
774 }
775
776 return NO_ERROR;
777 }
778
779 }; //namespace android
780