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