AudioOutputDescriptor.cpp revision c75307b73d324d590d0dbc05b44bce9aa89b7145
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 "HwModule.h"
25#include <media/AudioPolicy.h>
26
27// A device mask for all audio output devices that are considered "remote" when evaluating
28// active output devices in isStreamActiveRemotely()
29#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
30
31namespace android {
32
33AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
34                                             AudioPolicyClientInterface *clientInterface)
35    : mPort(port), mDevice(AUDIO_DEVICE_NONE),
36      mPatchHandle(0), mClientInterface(clientInterface), mId(0)
37{
38    // clear usage count for all stream types
39    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
40        mRefCount[i] = 0;
41        mCurVolume[i] = -1.0;
42        mMuteCount[i] = 0;
43        mStopTime[i] = 0;
44    }
45    for (int i = 0; i < NUM_STRATEGIES; i++) {
46        mStrategyMutedByDevice[i] = false;
47    }
48    if (port != NULL) {
49        mSamplingRate = port->pickSamplingRate();
50        mFormat = port->pickFormat();
51        mChannelMask = port->pickChannelMask();
52        if (port->mGains.size() > 0) {
53            port->mGains[0]->getDefaultConfig(&mGain);
54        }
55    }
56}
57
58audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
59{
60    return mPort->getModuleHandle();
61}
62
63audio_port_handle_t AudioOutputDescriptor::getId() const
64{
65    return mId;
66}
67
68audio_devices_t AudioOutputDescriptor::device() const
69{
70    return mDevice;
71}
72
73audio_devices_t AudioOutputDescriptor::supportedDevices()
74{
75    return mDevice;
76}
77
78bool 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 (getModuleHandle() == outputDesc->getModuleHandle());
86    }
87}
88
89void 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
102bool 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
119bool 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
139bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
140{
141    return false;
142}
143
144bool 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
161void 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
179void AudioOutputDescriptor::toAudioPort(
180                                                    struct audio_port *port) const
181{
182    mPort->toAudioPort(port);
183    port->id = mId;
184    port->ext.mix.hw_module = getModuleHandle();
185}
186
187status_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
215void 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
222SwAudioOutputDescriptor::SwAudioOutputDescriptor(
223        const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface)
224    : AudioOutputDescriptor(profile, clientInterface),
225    mProfile(profile), mIoHandle(0), mLatency(0),
226    mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
227    mOutput1(0), mOutput2(0), mDirectOpenCount(0)
228{
229    if (profile != NULL) {
230        mFlags = (audio_output_flags_t)profile->mFlags;
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->mSupportedDevices.types() ;
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
309
310bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
311{
312    // unit gain if rerouting to external policy
313    if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
314        if (mPolicyMix != NULL) {
315            ALOGV("max gain when rerouting for output=%d", mIoHandle);
316            return true;
317        }
318    }
319    return false;
320}
321
322void SwAudioOutputDescriptor::toAudioPortConfig(
323                                                 struct audio_port_config *dstConfig,
324                                                 const struct audio_port_config *srcConfig) const
325{
326
327    ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
328    AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
329
330    dstConfig->ext.mix.handle = mIoHandle;
331}
332
333void SwAudioOutputDescriptor::toAudioPort(
334                                                    struct audio_port *port) const
335{
336    ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
337
338    AudioOutputDescriptor::toAudioPort(port);
339
340    toAudioPortConfig(&port->active_config);
341    port->ext.mix.handle = mIoHandle;
342    port->ext.mix.latency_class =
343            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
344}
345
346bool SwAudioOutputDescriptor::setVolume(float volume,
347                                        audio_stream_type_t stream,
348                                        audio_devices_t device,
349                                        uint32_t delayMs,
350                                        bool force)
351{
352    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
353
354    if (changed) {
355        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
356        // enabled
357        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
358            mClientInterface->setStreamVolume(
359                    AUDIO_STREAM_VOICE_CALL, mCurVolume[stream], mIoHandle, delayMs);
360        }
361        mClientInterface->setStreamVolume(stream, mCurVolume[stream], mIoHandle, delayMs);
362    }
363    return changed;
364}
365
366// SwAudioOutputCollection implementation
367
368bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
369{
370    nsecs_t sysTime = systemTime();
371    for (size_t i = 0; i < this->size(); i++) {
372        const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
373        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
374            return true;
375        }
376    }
377    return false;
378}
379
380bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
381                                                   uint32_t inPastMs) const
382{
383    nsecs_t sysTime = systemTime();
384    for (size_t i = 0; i < size(); i++) {
385        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
386        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
387                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
388            // do not consider re routing (when the output is going to a dynamic policy)
389            // as "remote playback"
390            if (outputDesc->mPolicyMix == NULL) {
391                return true;
392            }
393        }
394    }
395    return false;
396}
397
398audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
399{
400    for (size_t i = 0; i < size(); i++) {
401        sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
402        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
403            return this->keyAt(i);
404        }
405    }
406    return 0;
407}
408
409sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
410{
411    for (size_t i = 0; i < size(); i++) {
412        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
413        if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
414            return outputDesc;
415        }
416    }
417    return NULL;
418}
419
420sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
421{
422    sp<SwAudioOutputDescriptor> outputDesc = NULL;
423    for (size_t i = 0; i < size(); i++) {
424        outputDesc = valueAt(i);
425        if (outputDesc->getId() == id) {
426            break;
427        }
428    }
429    return outputDesc;
430}
431
432bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
433{
434    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
435        if (s == (size_t) streamToIgnore) {
436            continue;
437        }
438        for (size_t i = 0; i < size(); i++) {
439            const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
440            if (outputDesc->mRefCount[s] != 0) {
441                return true;
442            }
443        }
444    }
445    return false;
446}
447
448audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
449{
450    sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
451    audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types();
452    return devices;
453}
454
455
456status_t SwAudioOutputCollection::dump(int fd) const
457{
458    const size_t SIZE = 256;
459    char buffer[SIZE];
460
461    snprintf(buffer, SIZE, "\nOutputs dump:\n");
462    write(fd, buffer, strlen(buffer));
463    for (size_t i = 0; i < size(); i++) {
464        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
465        write(fd, buffer, strlen(buffer));
466        valueAt(i)->dump(fd);
467    }
468
469    return NO_ERROR;
470}
471
472}; //namespace android
473