156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi/*
256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project
356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * you may not use this file except in compliance with the License.
656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * You may obtain a copy of the License at
756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
1056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * See the License for the specific language governing permissions and
1456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * limitations under the License.
1556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi */
1656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
1756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#define LOG_TAG "APM::AudioOutputDescriptor"
1856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define LOG_NDEBUG 0
1956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
20c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent#include <AudioPolicyInterface.h>
21ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "AudioOutputDescriptor.h"
22ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "IOProfile.h"
2398cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "AudioGain.h"
24ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent#include "Volume.h"
25ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "HwModule.h"
26ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <media/AudioPolicy.h>
2756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
2853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie// A device mask for all audio output devices that are considered "remote" when evaluating
2953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie// active output devices in isStreamActiveRemotely()
3053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
3153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
3256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android {
3356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
34c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentAudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
35c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                             AudioPolicyClientInterface *clientInterface)
36c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    : mPort(port), mDevice(AUDIO_DEVICE_NONE),
37a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten      mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
3856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
3956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // clear usage count for all stream types
4056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
4156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        mRefCount[i] = 0;
4256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        mCurVolume[i] = -1.0;
4356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        mMuteCount[i] = 0;
4456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        mStopTime[i] = 0;
4556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
4656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (int i = 0; i < NUM_STRATEGIES; i++) {
4756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        mStrategyMutedByDevice[i] = false;
4856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
49c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (port != NULL) {
50112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
51c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (port->mGains.size() > 0) {
52c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            port->mGains[0]->getDefaultConfig(&mGain);
5356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
5456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
5556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
5656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
5753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
5853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
59c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return mPort->getModuleHandle();
6053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
6153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
62322b4d25387a04c9afebe998326d005bbdf17edeEric Laurentaudio_port_handle_t AudioOutputDescriptor::getId() const
63322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent{
64322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    return mId;
65322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent}
66322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent
6756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Triviaudio_devices_t AudioOutputDescriptor::device() const
6856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
69c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return mDevice;
7056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
7156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
72c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t AudioOutputDescriptor::supportedDevices()
7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
74c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return mDevice;
7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
7656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::sharesHwModuleWith(
78e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const sp<AudioOutputDescriptor>& outputDesc)
7956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
80c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (outputDesc->isDuplicated()) {
81c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return sharesHwModuleWith(outputDesc->subOutput1()) ||
82c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    sharesHwModuleWith(outputDesc->subOutput2());
8356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    } else {
84fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return hasSameHwModuleAs(outputDesc);
8556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
8656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
8756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
8856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
8956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                                                                   int delta)
9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if ((delta + (int)mRefCount[stream]) < 0) {
9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi              delta, stream, mRefCount[stream]);
9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        mRefCount[stream] = 0;
9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        return;
9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    mRefCount[stream] += delta;
9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
9956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
103ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    nsecs_t sysTime = 0;
104ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    if (inPastMs != 0) {
10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        sysTime = systemTime();
10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (i == AUDIO_STREAM_PATCH) {
10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            continue;
11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
111ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie        if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            return true;
11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
11556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return false;
11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
11953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                           uint32_t inPastMs,
12053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                           nsecs_t sysTime) const
12156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
12256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (mRefCount[stream] != 0) {
12356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        return true;
12456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
12556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (inPastMs == 0) {
12656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        return false;
12756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
12856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (sysTime == 0) {
12956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        sysTime = systemTime();
13056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
13156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
13256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        return true;
13356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
13456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return false;
13556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
13656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
137c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
138c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
139c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
140c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return false;
141c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
142c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
143c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::setVolume(float volume,
144c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                      audio_stream_type_t stream,
145c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                      audio_devices_t device __unused,
146c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                      uint32_t delayMs,
147c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                      bool force)
148c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
149c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // We actually change the volume if:
150c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // - the float value returned by computeVolume() changed
151c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // - the force flag is set
152c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (volume != mCurVolume[stream] || force) {
153c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
154c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mCurVolume[stream] = volume;
155c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return true;
156c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
157c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return false;
158c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
159c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
16056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPortConfig(
16156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                                                 struct audio_port_config *dstConfig,
16256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                                                 const struct audio_port_config *srcConfig) const
16356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
16456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
16556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
16656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (srcConfig != NULL) {
16756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        dstConfig->config_mask |= srcConfig->config_mask;
16856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
16956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
17056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
17156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->id = mId;
17256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
17356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->type = AUDIO_PORT_TYPE_MIX;
174322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    dstConfig->ext.mix.hw_module = getModuleHandle();
17556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
17656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
17756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
17856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPort(
17956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                                                    struct audio_port *port) const
18056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
181c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    mPort->toAudioPort(port);
18256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->id = mId;
183322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    port->ext.mix.hw_module = getModuleHandle();
18456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
18556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
18656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t AudioOutputDescriptor::dump(int fd)
18756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
18856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    const size_t SIZE = 256;
18956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    char buffer[SIZE];
19056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    String8 result;
19156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
192c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    snprintf(buffer, SIZE, " ID: %d\n", mId);
19356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
19456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
19556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
19656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
19756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
19856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
19956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
20056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Devices %08x\n", device());
20156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
20256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
20356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
20456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
20556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
20656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
20756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        result.append(buffer);
20856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
20956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    write(fd, result.string(), result.size());
21056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
21156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return NO_ERROR;
21256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
21356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
214aa9811945f575614b3482d09e4d969792701cebbPaul McLeanvoid AudioOutputDescriptor::log(const char* indent)
215aa9811945f575614b3482d09e4d969792701cebbPaul McLean{
216c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
217c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent          indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
218c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
219c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
220c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent// SwAudioOutputDescriptor implementation
221d60560af7cb559762593161c8202459cc01fb0f5Eric LaurentSwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
222d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                 AudioPolicyClientInterface *clientInterface)
223c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    : AudioOutputDescriptor(profile, clientInterface),
224c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    mProfile(profile), mIoHandle(0), mLatency(0),
225c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
226169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard    mOutput1(0), mOutput2(0), mDirectOpenCount(0),
227169753cd5f71ba92560e993bb7cb461d2f094272Kevin Rocard    mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0)
228c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
229c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (profile != NULL) {
230a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        mFlags = (audio_output_flags_t)profile->getFlags();
231c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
232c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
233c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
234c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
235c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
236c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    mId = AudioPort::getNextUniqueId();
237c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    mIoHandle = ioHandle;
238c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
239c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
240c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
241c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputDescriptor::dump(int fd)
242c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
243c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    const size_t SIZE = 256;
244c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    char buffer[SIZE];
245c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    String8 result;
246c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
247c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
248c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    result.append(buffer);
249c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
250c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    result.append(buffer);
251c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    write(fd, result.string(), result.size());
252c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
253c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    AudioOutputDescriptor::dump(fd);
254c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
255c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return NO_ERROR;
256c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
257c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
258c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::device() const
259c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
260c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (isDuplicated()) {
261c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
262c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else {
263c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return mDevice;
264c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
265aa9811945f575614b3482d09e4d969792701cebbPaul McLean}
266aa9811945f575614b3482d09e4d969792701cebbPaul McLean
267c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::sharesHwModuleWith(
268e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const sp<AudioOutputDescriptor>& outputDesc)
269c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
270c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (isDuplicated()) {
271c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
272c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else if (outputDesc->isDuplicated()){
273c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return sharesHwModuleWith(outputDesc->subOutput1()) ||
274c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                    sharesHwModuleWith(outputDesc->subOutput2());
275c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else {
276c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
277c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
278c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
279c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
280c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::supportedDevices()
281c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
282c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (isDuplicated()) {
283c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
284c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else {
285a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        return mProfile->getSupportedDevicesType();
286c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
287c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
288c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
289c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentuint32_t SwAudioOutputDescriptor::latency()
290c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
291c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (isDuplicated()) {
292c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
293c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    } else {
294c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        return mLatency;
295c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
296c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
297c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
298c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
299c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                                   int delta)
300c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
301c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // forward usage count change to attached outputs
302c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (isDuplicated()) {
303c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mOutput1->changeRefCount(stream, delta);
304c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        mOutput2->changeRefCount(stream, delta);
305c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
306c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    AudioOutputDescriptor::changeRefCount(stream, delta);
307de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
308de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    // handle stream-independent ref count
309de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    uint32_t oldGlobalRefCount = mGlobalRefCount;
310de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    if ((delta + (int)mGlobalRefCount) < 0) {
311de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
312de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        mGlobalRefCount = 0;
313de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    } else {
314de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        mGlobalRefCount += delta;
315de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    }
316de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
317f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
318f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi        {
3197638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
320de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    MIX_STATE_MIXING);
321de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        }
322de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
323de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
324f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi        if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
325f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi        {
3267638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi            mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
327de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    MIX_STATE_IDLE);
328de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        }
329de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    }
330c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
331c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
332c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
333c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
334c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
335c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    // unit gain if rerouting to external policy
336c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
337c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (mPolicyMix != NULL) {
338c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            ALOGV("max gain when rerouting for output=%d", mIoHandle);
339c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            return true;
340c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        }
341c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
342c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return false;
343c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
344c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
345c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::toAudioPortConfig(
346c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                 struct audio_port_config *dstConfig,
347c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                 const struct audio_port_config *srcConfig) const
348c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
349c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
350c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
351c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
352c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
353c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    dstConfig->ext.mix.handle = mIoHandle;
354c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
355c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
356c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::toAudioPort(
357c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                                    struct audio_port *port) const
358c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
359c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
360c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
361c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    AudioOutputDescriptor::toAudioPort(port);
362c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
363c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    toAudioPortConfig(&port->active_config);
364c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    port->ext.mix.handle = mIoHandle;
365c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    port->ext.mix.latency_class =
366c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
367c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
368c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
369c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::setVolume(float volume,
370c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                        audio_stream_type_t stream,
371c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                        audio_devices_t device,
372c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                        uint32_t delayMs,
373c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent                                        bool force)
374c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{
375c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
376c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
377c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    if (changed) {
378c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
379c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        // enabled
380ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent        float volume = Volume::DbToAmpl(mCurVolume[stream]);
381c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
382c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            mClientInterface->setStreamVolume(
383ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent                    AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs);
384c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        }
385ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent        mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs);
386c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    }
387c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    return changed;
388c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent}
389c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
390d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent// HwAudioOutputDescriptor implementation
391d60560af7cb559762593161c8202459cc01fb0f5Eric LaurentHwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
392d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                 AudioPolicyClientInterface *clientInterface)
393d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    : AudioOutputDescriptor(source->mDevice, clientInterface),
394d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent      mSource(source)
395d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
396d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
397d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
398d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t HwAudioOutputDescriptor::dump(int fd)
399d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
400d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    const size_t SIZE = 256;
401d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    char buffer[SIZE];
402d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    String8 result;
403d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
404d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    AudioOutputDescriptor::dump(fd);
405d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
406d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    snprintf(buffer, SIZE, "Source:\n");
407d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    result.append(buffer);
408d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    write(fd, result.string(), result.size());
409d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    mSource->dump(fd);
410d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
411d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
412d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
413d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
414d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentaudio_devices_t HwAudioOutputDescriptor::supportedDevices()
415d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
416d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return mDevice;
417d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
418d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
419d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid HwAudioOutputDescriptor::toAudioPortConfig(
420d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                 struct audio_port_config *dstConfig,
421d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                 const struct audio_port_config *srcConfig) const
422d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
423d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig);
424d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
425d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
426d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid HwAudioOutputDescriptor::toAudioPort(
427d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                                    struct audio_port *port) const
428d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
429d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    mSource->mDevice->toAudioPort(port);
430d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
431d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
432d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
433d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentbool HwAudioOutputDescriptor::setVolume(float volume,
434d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                        audio_stream_type_t stream,
435d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                        audio_devices_t device,
436d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                        uint32_t delayMs,
437d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                                        bool force)
438d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
439d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
440d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
441d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    if (changed) {
442d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent      // TODO: use gain controller on source device if any to adjust volume
443d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
444d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return changed;
445d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
446c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent
447d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent// SwAudioOutputCollection implementation
448c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
44953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
45053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    nsecs_t sysTime = systemTime();
45153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < this->size(); i++) {
452c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
45353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
45453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            return true;
45553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
45653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
45753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return false;
45853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
45953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
460c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
46153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                                                   uint32_t inPastMs) const
46253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
46353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    nsecs_t sysTime = systemTime();
46453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
465c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
46653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
46753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
46853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            // do not consider re routing (when the output is going to a dynamic policy)
46953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            // as "remote playback"
47053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (outputDesc->mPolicyMix == NULL) {
47153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                return true;
47253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            }
47353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
47453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
47553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return false;
47653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
47753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
478c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
47953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
48053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
481c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
48253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
48353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            return this->keyAt(i);
48453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
48553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
48653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return 0;
48753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
48853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
489c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
49053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
49153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
492c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
49353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
49453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            return outputDesc;
49553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
49653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
49753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return NULL;
49853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
49956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
500c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
50153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
502c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = NULL;
50353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
50453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        outputDesc = valueAt(i);
505322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        if (outputDesc->getId() == id) {
50653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            break;
50753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
50853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
50953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return outputDesc;
51053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
51153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
512c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
51353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
51453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
51553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (s == (size_t) streamToIgnore) {
51653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            continue;
51753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
51853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        for (size_t i = 0; i < size(); i++) {
519c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent            const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
52053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            if (outputDesc->mRefCount[s] != 0) {
52153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                return true;
52253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            }
52353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
52453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
52553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return false;
52653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
52753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
528c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
52953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
530c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent    sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
531a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType();
53253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return devices;
53353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
53453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
53553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
536c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputCollection::dump(int fd) const
53753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
53853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    const size_t SIZE = 256;
53953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    char buffer[SIZE];
54053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
54153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    snprintf(buffer, SIZE, "\nOutputs dump:\n");
54253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    write(fd, buffer, strlen(buffer));
54353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
54453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
54553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        write(fd, buffer, strlen(buffer));
54653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        valueAt(i)->dump(fd);
54753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
54853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
54953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return NO_ERROR;
55053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
55156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
552d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent// HwAudioOutputCollection implementation
553d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentbool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
554d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
555d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    nsecs_t sysTime = systemTime();
556d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (size_t i = 0; i < this->size(); i++) {
557d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
558d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
559d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            return true;
560d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
561d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
562d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return false;
563d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
564d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
565d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentbool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
566d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
567d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
568d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        if (s == (size_t) streamToIgnore) {
569d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            continue;
570d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
571d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        for (size_t i = 0; i < size(); i++) {
572d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i);
573d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            if (outputDesc->mRefCount[s] != 0) {
574d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent                return true;
575d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent            }
576d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        }
577d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
578d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return false;
579d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
580d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
581d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t HwAudioOutputCollection::dump(int fd) const
582d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{
583d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    const size_t SIZE = 256;
584d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    char buffer[SIZE];
585d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
586d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    snprintf(buffer, SIZE, "\nOutputs dump:\n");
587d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    write(fd, buffer, strlen(buffer));
588d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    for (size_t i = 0; i < size(); i++) {
589d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
590d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        write(fd, buffer, strlen(buffer));
591d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent        valueAt(i)->dump(fd);
592d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    }
593d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
594d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent    return NO_ERROR;
595d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent}
596d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent
59756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; //namespace android
598