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