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 hasSameHwModuleAs(outputDesc);
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),
227    mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0)
228{
229    if (profile != NULL) {
230        mFlags = (audio_output_flags_t)profile->getFlags();
231    }
232}
233
234void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
235{
236    mId = AudioPort::getNextUniqueId();
237    mIoHandle = ioHandle;
238}
239
240
241status_t SwAudioOutputDescriptor::dump(int fd)
242{
243    const size_t SIZE = 256;
244    char buffer[SIZE];
245    String8 result;
246
247    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
248    result.append(buffer);
249    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
250    result.append(buffer);
251    write(fd, result.string(), result.size());
252
253    AudioOutputDescriptor::dump(fd);
254
255    return NO_ERROR;
256}
257
258audio_devices_t SwAudioOutputDescriptor::device() const
259{
260    if (isDuplicated()) {
261        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
262    } else {
263        return mDevice;
264    }
265}
266
267bool SwAudioOutputDescriptor::sharesHwModuleWith(
268        const sp<AudioOutputDescriptor>& outputDesc)
269{
270    if (isDuplicated()) {
271        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
272    } else if (outputDesc->isDuplicated()){
273        return sharesHwModuleWith(outputDesc->subOutput1()) ||
274                    sharesHwModuleWith(outputDesc->subOutput2());
275    } else {
276        return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
277    }
278}
279
280audio_devices_t SwAudioOutputDescriptor::supportedDevices()
281{
282    if (isDuplicated()) {
283        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
284    } else {
285        return mProfile->getSupportedDevicesType();
286    }
287}
288
289uint32_t SwAudioOutputDescriptor::latency()
290{
291    if (isDuplicated()) {
292        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
293    } else {
294        return mLatency;
295    }
296}
297
298void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
299                                                                   int delta)
300{
301    // forward usage count change to attached outputs
302    if (isDuplicated()) {
303        mOutput1->changeRefCount(stream, delta);
304        mOutput2->changeRefCount(stream, delta);
305    }
306    AudioOutputDescriptor::changeRefCount(stream, delta);
307
308    // handle stream-independent ref count
309    uint32_t oldGlobalRefCount = mGlobalRefCount;
310    if ((delta + (int)mGlobalRefCount) < 0) {
311        ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
312        mGlobalRefCount = 0;
313    } else {
314        mGlobalRefCount += delta;
315    }
316    if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
317        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
318        {
319            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
320                    MIX_STATE_MIXING);
321        }
322
323    } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
324        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
325        {
326            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
327                    MIX_STATE_IDLE);
328        }
329    }
330}
331
332
333bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
334{
335    // unit gain if rerouting to external policy
336    if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
337        if (mPolicyMix != NULL) {
338            ALOGV("max gain when rerouting for output=%d", mIoHandle);
339            return true;
340        }
341    }
342    return false;
343}
344
345void 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
356void 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
369bool 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
390// HwAudioOutputDescriptor implementation
391HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
392                                                 AudioPolicyClientInterface *clientInterface)
393    : AudioOutputDescriptor(source->mDevice, clientInterface),
394      mSource(source)
395{
396}
397
398status_t HwAudioOutputDescriptor::dump(int fd)
399{
400    const size_t SIZE = 256;
401    char buffer[SIZE];
402    String8 result;
403
404    AudioOutputDescriptor::dump(fd);
405
406    snprintf(buffer, SIZE, "Source:\n");
407    result.append(buffer);
408    write(fd, result.string(), result.size());
409    mSource->dump(fd);
410
411    return NO_ERROR;
412}
413
414audio_devices_t HwAudioOutputDescriptor::supportedDevices()
415{
416    return mDevice;
417}
418
419void HwAudioOutputDescriptor::toAudioPortConfig(
420                                                 struct audio_port_config *dstConfig,
421                                                 const struct audio_port_config *srcConfig) const
422{
423    mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig);
424}
425
426void HwAudioOutputDescriptor::toAudioPort(
427                                                    struct audio_port *port) const
428{
429    mSource->mDevice->toAudioPort(port);
430}
431
432
433bool HwAudioOutputDescriptor::setVolume(float volume,
434                                        audio_stream_type_t stream,
435                                        audio_devices_t device,
436                                        uint32_t delayMs,
437                                        bool force)
438{
439    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
440
441    if (changed) {
442      // TODO: use gain controller on source device if any to adjust volume
443    }
444    return changed;
445}
446
447// SwAudioOutputCollection implementation
448bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
449{
450    nsecs_t sysTime = systemTime();
451    for (size_t i = 0; i < this->size(); i++) {
452        const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
453        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
454            return true;
455        }
456    }
457    return false;
458}
459
460bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
461                                                   uint32_t inPastMs) const
462{
463    nsecs_t sysTime = systemTime();
464    for (size_t i = 0; i < size(); i++) {
465        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
466        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
467                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
468            // do not consider re routing (when the output is going to a dynamic policy)
469            // as "remote playback"
470            if (outputDesc->mPolicyMix == NULL) {
471                return true;
472            }
473        }
474    }
475    return false;
476}
477
478audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
479{
480    for (size_t i = 0; i < size(); i++) {
481        sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
482        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
483            return this->keyAt(i);
484        }
485    }
486    return 0;
487}
488
489sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
490{
491    for (size_t i = 0; i < size(); i++) {
492        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
493        if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
494            return outputDesc;
495        }
496    }
497    return NULL;
498}
499
500sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
501{
502    sp<SwAudioOutputDescriptor> outputDesc = NULL;
503    for (size_t i = 0; i < size(); i++) {
504        outputDesc = valueAt(i);
505        if (outputDesc->getId() == id) {
506            break;
507        }
508    }
509    return outputDesc;
510}
511
512bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
513{
514    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
515        if (s == (size_t) streamToIgnore) {
516            continue;
517        }
518        for (size_t i = 0; i < size(); i++) {
519            const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
520            if (outputDesc->mRefCount[s] != 0) {
521                return true;
522            }
523        }
524    }
525    return false;
526}
527
528audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
529{
530    sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
531    audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType();
532    return devices;
533}
534
535
536status_t SwAudioOutputCollection::dump(int fd) const
537{
538    const size_t SIZE = 256;
539    char buffer[SIZE];
540
541    snprintf(buffer, SIZE, "\nOutputs dump:\n");
542    write(fd, buffer, strlen(buffer));
543    for (size_t i = 0; i < size(); i++) {
544        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
545        write(fd, buffer, strlen(buffer));
546        valueAt(i)->dump(fd);
547    }
548
549    return NO_ERROR;
550}
551
552// HwAudioOutputCollection implementation
553bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
554{
555    nsecs_t sysTime = systemTime();
556    for (size_t i = 0; i < this->size(); i++) {
557        const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
558        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
559            return true;
560        }
561    }
562    return false;
563}
564
565bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
566{
567    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
568        if (s == (size_t) streamToIgnore) {
569            continue;
570        }
571        for (size_t i = 0; i < size(); i++) {
572            const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i);
573            if (outputDesc->mRefCount[s] != 0) {
574                return true;
575            }
576        }
577    }
578    return false;
579}
580
581status_t HwAudioOutputCollection::dump(int fd) const
582{
583    const size_t SIZE = 256;
584    char buffer[SIZE];
585
586    snprintf(buffer, SIZE, "\nOutputs dump:\n");
587    write(fd, buffer, strlen(buffer));
588    for (size_t i = 0; i < size(); i++) {
589        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
590        write(fd, buffer, strlen(buffer));
591        valueAt(i)->dump(fd);
592    }
593
594    return NO_ERROR;
595}
596
597}; //namespace android
598