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/AudioPolicy.h>
27
28// A device mask for all audio output devices that are considered "remote" when evaluating
29// active output devices in isStreamActiveRemotely()
30#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
31
32namespace android {
33
34AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
35                                             AudioPolicyClientInterface *clientInterface)
36    : mPort(port), mDevice(AUDIO_DEVICE_NONE),
37      mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
38{
39    // clear usage count for all stream types
40    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
41        mRefCount[i] = 0;
42        mCurVolume[i] = -1.0;
43        mMuteCount[i] = 0;
44        mStopTime[i] = 0;
45    }
46    for (int i = 0; i < NUM_STRATEGIES; i++) {
47        mStrategyMutedByDevice[i] = false;
48    }
49    if (port != NULL) {
50        port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
51        if (port->mGains.size() > 0) {
52            port->mGains[0]->getDefaultConfig(&mGain);
53        }
54    }
55}
56
57audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
58{
59    return mPort->getModuleHandle();
60}
61
62audio_port_handle_t AudioOutputDescriptor::getId() const
63{
64    return mId;
65}
66
67audio_devices_t AudioOutputDescriptor::device() const
68{
69    return mDevice;
70}
71
72audio_devices_t AudioOutputDescriptor::supportedDevices()
73{
74    return mDevice;
75}
76
77bool AudioOutputDescriptor::sharesHwModuleWith(
78        const sp<AudioOutputDescriptor> outputDesc)
79{
80    if (outputDesc->isDuplicated()) {
81        return sharesHwModuleWith(outputDesc->subOutput1()) ||
82                    sharesHwModuleWith(outputDesc->subOutput2());
83    } else {
84        return (getModuleHandle() == outputDesc->getModuleHandle());
85    }
86}
87
88void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
89                                                                   int delta)
90{
91    if ((delta + (int)mRefCount[stream]) < 0) {
92        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
93              delta, stream, mRefCount[stream]);
94        mRefCount[stream] = 0;
95        return;
96    }
97    mRefCount[stream] += delta;
98    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
99}
100
101bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
102{
103    nsecs_t sysTime = 0;
104    if (inPastMs != 0) {
105        sysTime = systemTime();
106    }
107    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
108        if (i == AUDIO_STREAM_PATCH) {
109            continue;
110        }
111        if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
112            return true;
113        }
114    }
115    return false;
116}
117
118bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
119                                           uint32_t inPastMs,
120                                           nsecs_t sysTime) const
121{
122    if (mRefCount[stream] != 0) {
123        return true;
124    }
125    if (inPastMs == 0) {
126        return false;
127    }
128    if (sysTime == 0) {
129        sysTime = systemTime();
130    }
131    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
132        return true;
133    }
134    return false;
135}
136
137
138bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
139{
140    return false;
141}
142
143bool AudioOutputDescriptor::setVolume(float volume,
144                                      audio_stream_type_t stream,
145                                      audio_devices_t device __unused,
146                                      uint32_t delayMs,
147                                      bool force)
148{
149    // We actually change the volume if:
150    // - the float value returned by computeVolume() changed
151    // - the force flag is set
152    if (volume != mCurVolume[stream] || force) {
153        ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
154        mCurVolume[stream] = volume;
155        return true;
156    }
157    return false;
158}
159
160void AudioOutputDescriptor::toAudioPortConfig(
161                                                 struct audio_port_config *dstConfig,
162                                                 const struct audio_port_config *srcConfig) const
163{
164    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
165                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
166    if (srcConfig != NULL) {
167        dstConfig->config_mask |= srcConfig->config_mask;
168    }
169    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
170
171    dstConfig->id = mId;
172    dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
173    dstConfig->type = AUDIO_PORT_TYPE_MIX;
174    dstConfig->ext.mix.hw_module = getModuleHandle();
175    dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
176}
177
178void AudioOutputDescriptor::toAudioPort(
179                                                    struct audio_port *port) const
180{
181    mPort->toAudioPort(port);
182    port->id = mId;
183    port->ext.mix.hw_module = getModuleHandle();
184}
185
186status_t AudioOutputDescriptor::dump(int fd)
187{
188    const size_t SIZE = 256;
189    char buffer[SIZE];
190    String8 result;
191
192    snprintf(buffer, SIZE, " ID: %d\n", mId);
193    result.append(buffer);
194    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
195    result.append(buffer);
196    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
197    result.append(buffer);
198    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
199    result.append(buffer);
200    snprintf(buffer, SIZE, " Devices %08x\n", device());
201    result.append(buffer);
202    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
203    result.append(buffer);
204    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
205        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
206                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
207        result.append(buffer);
208    }
209    write(fd, result.string(), result.size());
210
211    return NO_ERROR;
212}
213
214void AudioOutputDescriptor::log(const char* indent)
215{
216    ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
217          indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
218}
219
220// SwAudioOutputDescriptor implementation
221SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
222                                                 AudioPolicyClientInterface *clientInterface)
223    : AudioOutputDescriptor(profile, clientInterface),
224    mProfile(profile), mIoHandle(0), mLatency(0),
225    mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
226    mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0)
227{
228    if (profile != NULL) {
229        mFlags = (audio_output_flags_t)profile->getFlags();
230    }
231}
232
233void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
234{
235    mId = AudioPort::getNextUniqueId();
236    mIoHandle = ioHandle;
237}
238
239
240status_t SwAudioOutputDescriptor::dump(int fd)
241{
242    const size_t SIZE = 256;
243    char buffer[SIZE];
244    String8 result;
245
246    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
247    result.append(buffer);
248    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
249    result.append(buffer);
250    write(fd, result.string(), result.size());
251
252    AudioOutputDescriptor::dump(fd);
253
254    return NO_ERROR;
255}
256
257audio_devices_t SwAudioOutputDescriptor::device() const
258{
259    if (isDuplicated()) {
260        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
261    } else {
262        return mDevice;
263    }
264}
265
266bool SwAudioOutputDescriptor::sharesHwModuleWith(
267        const sp<AudioOutputDescriptor> outputDesc)
268{
269    if (isDuplicated()) {
270        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
271    } else if (outputDesc->isDuplicated()){
272        return sharesHwModuleWith(outputDesc->subOutput1()) ||
273                    sharesHwModuleWith(outputDesc->subOutput2());
274    } else {
275        return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
276    }
277}
278
279audio_devices_t SwAudioOutputDescriptor::supportedDevices()
280{
281    if (isDuplicated()) {
282        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
283    } else {
284        return mProfile->getSupportedDevicesType();
285    }
286}
287
288uint32_t SwAudioOutputDescriptor::latency()
289{
290    if (isDuplicated()) {
291        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
292    } else {
293        return mLatency;
294    }
295}
296
297void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
298                                                                   int delta)
299{
300    // forward usage count change to attached outputs
301    if (isDuplicated()) {
302        mOutput1->changeRefCount(stream, delta);
303        mOutput2->changeRefCount(stream, delta);
304    }
305    AudioOutputDescriptor::changeRefCount(stream, delta);
306
307    // handle stream-independent ref count
308    uint32_t oldGlobalRefCount = mGlobalRefCount;
309    if ((delta + (int)mGlobalRefCount) < 0) {
310        ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
311        mGlobalRefCount = 0;
312    } else {
313        mGlobalRefCount += delta;
314    }
315    if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
316        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
317        {
318            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
319                    MIX_STATE_MIXING);
320        }
321
322    } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
323        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
324        {
325            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
326                    MIX_STATE_IDLE);
327        }
328    }
329}
330
331
332bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
333{
334    // unit gain if rerouting to external policy
335    if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
336        if (mPolicyMix != NULL) {
337            ALOGV("max gain when rerouting for output=%d", mIoHandle);
338            return true;
339        }
340    }
341    return false;
342}
343
344void SwAudioOutputDescriptor::toAudioPortConfig(
345                                                 struct audio_port_config *dstConfig,
346                                                 const struct audio_port_config *srcConfig) const
347{
348
349    ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
350    AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
351
352    dstConfig->ext.mix.handle = mIoHandle;
353}
354
355void SwAudioOutputDescriptor::toAudioPort(
356                                                    struct audio_port *port) const
357{
358    ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
359
360    AudioOutputDescriptor::toAudioPort(port);
361
362    toAudioPortConfig(&port->active_config);
363    port->ext.mix.handle = mIoHandle;
364    port->ext.mix.latency_class =
365            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
366}
367
368bool SwAudioOutputDescriptor::setVolume(float volume,
369                                        audio_stream_type_t stream,
370                                        audio_devices_t device,
371                                        uint32_t delayMs,
372                                        bool force)
373{
374    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
375
376    if (changed) {
377        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
378        // enabled
379        float volume = Volume::DbToAmpl(mCurVolume[stream]);
380        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
381            mClientInterface->setStreamVolume(
382                    AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs);
383        }
384        mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs);
385    }
386    return changed;
387}
388
389// HwAudioOutputDescriptor implementation
390HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
391                                                 AudioPolicyClientInterface *clientInterface)
392    : AudioOutputDescriptor(source->mDevice, clientInterface),
393      mSource(source)
394{
395}
396
397status_t HwAudioOutputDescriptor::dump(int fd)
398{
399    const size_t SIZE = 256;
400    char buffer[SIZE];
401    String8 result;
402
403    AudioOutputDescriptor::dump(fd);
404
405    snprintf(buffer, SIZE, "Source:\n");
406    result.append(buffer);
407    write(fd, result.string(), result.size());
408    mSource->dump(fd);
409
410    return NO_ERROR;
411}
412
413audio_devices_t HwAudioOutputDescriptor::supportedDevices()
414{
415    return mDevice;
416}
417
418void HwAudioOutputDescriptor::toAudioPortConfig(
419                                                 struct audio_port_config *dstConfig,
420                                                 const struct audio_port_config *srcConfig) const
421{
422    mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig);
423}
424
425void HwAudioOutputDescriptor::toAudioPort(
426                                                    struct audio_port *port) const
427{
428    mSource->mDevice->toAudioPort(port);
429}
430
431
432bool HwAudioOutputDescriptor::setVolume(float volume,
433                                        audio_stream_type_t stream,
434                                        audio_devices_t device,
435                                        uint32_t delayMs,
436                                        bool force)
437{
438    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
439
440    if (changed) {
441      // TODO: use gain controller on source device if any to adjust volume
442    }
443    return changed;
444}
445
446// SwAudioOutputCollection implementation
447bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
448{
449    nsecs_t sysTime = systemTime();
450    for (size_t i = 0; i < this->size(); i++) {
451        const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
452        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
453            return true;
454        }
455    }
456    return false;
457}
458
459bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
460                                                   uint32_t inPastMs) const
461{
462    nsecs_t sysTime = systemTime();
463    for (size_t i = 0; i < size(); i++) {
464        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
465        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
466                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
467            // do not consider re routing (when the output is going to a dynamic policy)
468            // as "remote playback"
469            if (outputDesc->mPolicyMix == NULL) {
470                return true;
471            }
472        }
473    }
474    return false;
475}
476
477audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
478{
479    for (size_t i = 0; i < size(); i++) {
480        sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
481        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
482            return this->keyAt(i);
483        }
484    }
485    return 0;
486}
487
488sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
489{
490    for (size_t i = 0; i < size(); i++) {
491        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
492        if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
493            return outputDesc;
494        }
495    }
496    return NULL;
497}
498
499sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
500{
501    sp<SwAudioOutputDescriptor> outputDesc = NULL;
502    for (size_t i = 0; i < size(); i++) {
503        outputDesc = valueAt(i);
504        if (outputDesc->getId() == id) {
505            break;
506        }
507    }
508    return outputDesc;
509}
510
511bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
512{
513    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
514        if (s == (size_t) streamToIgnore) {
515            continue;
516        }
517        for (size_t i = 0; i < size(); i++) {
518            const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
519            if (outputDesc->mRefCount[s] != 0) {
520                return true;
521            }
522        }
523    }
524    return false;
525}
526
527audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
528{
529    sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
530    audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType();
531    return devices;
532}
533
534
535status_t SwAudioOutputCollection::dump(int fd) const
536{
537    const size_t SIZE = 256;
538    char buffer[SIZE];
539
540    snprintf(buffer, SIZE, "\nOutputs dump:\n");
541    write(fd, buffer, strlen(buffer));
542    for (size_t i = 0; i < size(); i++) {
543        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
544        write(fd, buffer, strlen(buffer));
545        valueAt(i)->dump(fd);
546    }
547
548    return NO_ERROR;
549}
550
551// HwAudioOutputCollection implementation
552bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
553{
554    nsecs_t sysTime = systemTime();
555    for (size_t i = 0; i < this->size(); i++) {
556        const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
557        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
558            return true;
559        }
560    }
561    return false;
562}
563
564bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
565{
566    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
567        if (s == (size_t) streamToIgnore) {
568            continue;
569        }
570        for (size_t i = 0; i < size(); i++) {
571            const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i);
572            if (outputDesc->mRefCount[s] != 0) {
573                return true;
574            }
575        }
576    }
577    return false;
578}
579
580status_t HwAudioOutputCollection::dump(int fd) const
581{
582    const size_t SIZE = 256;
583    char buffer[SIZE];
584
585    snprintf(buffer, SIZE, "\nOutputs dump:\n");
586    write(fd, buffer, strlen(buffer));
587    for (size_t i = 0; i < size(); i++) {
588        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
589        write(fd, buffer, strlen(buffer));
590        valueAt(i)->dump(fd);
591    }
592
593    return NO_ERROR;
594}
595
596}; //namespace android
597