Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c75307b7 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: volume control reorganization

Output volume and routing control by AudioOutputDescriptor
is reorganized to prepare hardware source volume and routing
control.
AudioOutputDescriptor contains all volume, device and activity
state common to software (audio flinger mixers) and
hardware sources (tuners, A2DP, HDMI).
A new class SwAudioOutputDescriptor is derived from
AudioOutputDescriptor and is specific to software sources.

Low level routing and volume control methods receive an
AudioOutputDescriptor parameter instead of an IO handle.

mPrimaryOutput is now an AudioOutputDescriptor.

Change-Id: Ie90943ee3102cdb8adf89fdd2addd2c279b1e5bf
parent 303db9de
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_C_INCLUDES += \
    $(LOCAL_PATH)/include \
    $(TOPDIR)frameworks/av/services/audiopolicy/common/include \
    $(TOPDIR)frameworks/av/services/audiopolicy

LOCAL_EXPORT_C_INCLUDE_DIRS := \
    $(LOCAL_PATH)/include
+69 −23
Original line number Diff line number Diff line
@@ -27,25 +27,36 @@ namespace android {

class IOProfile;
class AudioMix;
class AudioPolicyClientInterface;

// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
class AudioOutputDescriptor: public AudioPortConfig
{
public:
    AudioOutputDescriptor(const sp<IOProfile>& profile);
    AudioOutputDescriptor(const sp<AudioPort>& port,
                          AudioPolicyClientInterface *clientInterface);
    virtual ~AudioOutputDescriptor() {}

    status_t    dump(int fd);
    void        log(const char* indent);

    audio_devices_t device() const;
    void changeRefCount(audio_stream_type_t stream, int delta);
    audio_port_handle_t getId() const;
    void setIoHandle(audio_io_handle_t ioHandle);
    bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
    audio_devices_t supportedDevices();
    uint32_t latency();
    bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
    virtual audio_devices_t device() const;
    virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
    virtual audio_devices_t supportedDevices();
    virtual bool isDuplicated() const { return false; }
    virtual uint32_t latency() { return 0; }
    virtual bool isFixedVolume(audio_devices_t device);
    virtual sp<AudioOutputDescriptor> subOutput1() { return 0; }
    virtual sp<AudioOutputDescriptor> subOutput2() { return 0; }
    virtual bool setVolume(float volume,
                           audio_stream_type_t stream,
                           audio_devices_t device,
                           uint32_t delayMs,
                           bool force);
    virtual void changeRefCount(audio_stream_type_t stream, int delta);

    bool isActive(uint32_t inPastMs = 0) const;
    bool isStreamActive(audio_stream_type_t stream,
                        uint32_t inPastMs = 0,
@@ -53,34 +64,69 @@ public:

    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                           const struct audio_port_config *srcConfig = NULL) const;
    virtual sp<AudioPort> getAudioPort() const { return mProfile; }
    void toAudioPort(struct audio_port *port) const;
    virtual sp<AudioPort> getAudioPort() const { return mPort; }
    virtual void toAudioPort(struct audio_port *port) const;

    audio_module_handle_t getModuleHandle() const;

    audio_io_handle_t mIoHandle;              // output handle
    uint32_t mLatency;                  //
    audio_output_flags_t mFlags;   //
    sp<AudioPort>       mPort;
    audio_devices_t mDevice;                   // current device this output is routed to
    AudioMix *mPolicyMix;             // non NULL when used by a dynamic policy
    audio_patch_handle_t mPatchHandle;
    uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
    nsecs_t mStopTime[AUDIO_STREAM_CNT];
    sp<AudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
    sp<AudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
    float mCurVolume[AUDIO_STREAM_CNT];   // current stream volume
    int mMuteCount[AUDIO_STREAM_CNT];     // mute request counter
    const sp<IOProfile> mProfile;          // I/O profile this output derives from
    bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
                                        // device selection. See checkDeviceMuteStrategies()
    uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
    AudioPolicyClientInterface *mClientInterface;

private:
protected:
    audio_port_handle_t mId;
};

class AudioOutputCollection :
        public DefaultKeyedVector< audio_io_handle_t, sp<AudioOutputDescriptor> >
// Audio output driven by a software mixer in audio flinger.
class SwAudioOutputDescriptor: public AudioOutputDescriptor
{
public:
    SwAudioOutputDescriptor(const sp<IOProfile>& profile,
                            AudioPolicyClientInterface *clientInterface);
    virtual ~SwAudioOutputDescriptor() {}

    status_t    dump(int fd);

    void setIoHandle(audio_io_handle_t ioHandle);

    virtual audio_devices_t device() const;
    virtual bool sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc);
    virtual audio_devices_t supportedDevices();
    virtual uint32_t latency();
    virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
    virtual bool isFixedVolume(audio_devices_t device);
    virtual sp<AudioOutputDescriptor> subOutput1() { return mOutput1; }
    virtual sp<AudioOutputDescriptor> subOutput2() { return mOutput2; }
    virtual void changeRefCount(audio_stream_type_t stream, int delta);
    virtual bool setVolume(float volume,
                           audio_stream_type_t stream,
                           audio_devices_t device,
                           uint32_t delayMs,
                           bool force);

    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                           const struct audio_port_config *srcConfig = NULL) const;
    virtual void toAudioPort(struct audio_port *port) const;

    const sp<IOProfile> mProfile;          // I/O profile this output derives from
    audio_io_handle_t mIoHandle;           // output handle
    uint32_t mLatency;                  //
    audio_output_flags_t mFlags;   //
    AudioMix *mPolicyMix;             // non NULL when used by a dynamic policy
    sp<SwAudioOutputDescriptor> mOutput1;    // used by duplicated outputs: first output
    sp<SwAudioOutputDescriptor> mOutput2;    // used by duplicated outputs: second output
    uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
};

class SwAudioOutputCollection :
        public DefaultKeyedVector< audio_io_handle_t, sp<SwAudioOutputDescriptor> >
{
public:
    bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
@@ -99,9 +145,9 @@ public:
     */
    audio_io_handle_t getA2dpOutput() const;

    sp<AudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;
    sp<SwAudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;

    sp<AudioOutputDescriptor> getPrimaryOutput() const;
    sp<SwAudioOutputDescriptor> getPrimaryOutput() const;

    /**
     * return true if any output is playing anything besides the stream to ignore
+7 −7
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

namespace android {

class AudioOutputDescriptor;
class SwAudioOutputDescriptor;

/**
 * custom mix entry in mPolicyMixes
@@ -33,9 +33,9 @@ class AudioPolicyMix : public RefBase {
public:
    AudioPolicyMix() {}

    const sp<AudioOutputDescriptor> &getOutput() const;
    const sp<SwAudioOutputDescriptor> &getOutput() const;

    void setOutput(sp<AudioOutputDescriptor> &output);
    void setOutput(sp<SwAudioOutputDescriptor> &output);

    void clearOutput();

@@ -45,7 +45,7 @@ public:

private:
    AudioMix    mMix;                   // Audio policy mix descriptor
    sp<AudioOutputDescriptor> mOutput;  // Corresponding output stream
    sp<SwAudioOutputDescriptor> mOutput;  // Corresponding output stream
};


@@ -58,18 +58,18 @@ public:

    status_t unregisterMix(String8 address);

    void closeOutput(sp<AudioOutputDescriptor> &desc);
    void closeOutput(sp<SwAudioOutputDescriptor> &desc);

    /**
     * Try to find an output descriptor for the given attributes.
     *
     * @param[in] attributes to consider for the research of output descriptor.
     * @param[in] attributes to consider fowr the research of output descriptor.
     * @param[out] desc to return if an output could be found.
     *
     * @return NO_ERROR if an output was found for the given attribute (in this case, the
     *                  descriptor output param is initialized), error code otherwise.
     */
    status_t getOutputForAttr(audio_attributes_t attributes, sp<AudioOutputDescriptor> &desc);
    status_t getOutputForAttr(audio_attributes_t attributes, sp<SwAudioOutputDescriptor> &desc);

    audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
                                                  audio_devices_t availableDeviceTypes,
+207 −83
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "APM::AudioOutputDescriptor"
//#define LOG_NDEBUG 0

#include <AudioPolicyInterface.h>
#include "AudioOutputDescriptor.h"
#include "IOProfile.h"
#include "AudioGain.h"
@@ -29,12 +30,10 @@

namespace android {

AudioOutputDescriptor::AudioOutputDescriptor(const sp<IOProfile>& profile)
    : mIoHandle(0), mLatency(0),
    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
    mPatchHandle(0),
    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0),
    mId(0)
AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
                                             AudioPolicyClientInterface *clientInterface)
    : mPort(port), mDevice(AUDIO_DEVICE_NONE),
      mPatchHandle(0), mClientInterface(clientInterface), mId(0)
{
    // clear usage count for all stream types
    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
@@ -46,23 +45,19 @@ AudioOutputDescriptor::AudioOutputDescriptor(const sp<IOProfile>& profile)
    for (int i = 0; i < NUM_STRATEGIES; i++) {
        mStrategyMutedByDevice[i] = false;
    }
    if (profile != NULL) {
        mFlags = (audio_output_flags_t)profile->mFlags;
        mSamplingRate = profile->pickSamplingRate();
        mFormat = profile->pickFormat();
        mChannelMask = profile->pickChannelMask();
        if (profile->mGains.size() > 0) {
            profile->mGains[0]->getDefaultConfig(&mGain);
    if (port != NULL) {
        mSamplingRate = port->pickSamplingRate();
        mFormat = port->pickFormat();
        mChannelMask = port->pickChannelMask();
        if (port->mGains.size() > 0) {
            port->mGains[0]->getDefaultConfig(&mGain);
        }
    }
}

audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
{
    if (mProfile == 0) {
        return 0;
    }
    return mProfile->getModuleHandle();
    return mPort->getModuleHandle();
}

audio_port_handle_t AudioOutputDescriptor::getId() const
@@ -72,35 +67,20 @@ audio_port_handle_t AudioOutputDescriptor::getId() const

audio_devices_t AudioOutputDescriptor::device() const
{
    if (isDuplicated()) {
        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
    } else {
    return mDevice;
}
}

void AudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
{
    mId = AudioPort::getNextUniqueId();
    mIoHandle = ioHandle;
}

uint32_t AudioOutputDescriptor::latency()
audio_devices_t AudioOutputDescriptor::supportedDevices()
{
    if (isDuplicated()) {
        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
    } else {
        return mLatency;
    }
    return mDevice;
}

bool AudioOutputDescriptor::sharesHwModuleWith(
        const sp<AudioOutputDescriptor> outputDesc)
{
    if (isDuplicated()) {
        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
    } else if (outputDesc->isDuplicated()){
        return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
    if (outputDesc->isDuplicated()) {
        return sharesHwModuleWith(outputDesc->subOutput1()) ||
                    sharesHwModuleWith(outputDesc->subOutput2());
    } else {
        return (getModuleHandle() == outputDesc->getModuleHandle());
    }
@@ -109,11 +89,6 @@ bool AudioOutputDescriptor::sharesHwModuleWith(
void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
                                                                   int delta)
{
    // forward usage count change to attached outputs
    if (isDuplicated()) {
        mOutput1->changeRefCount(stream, delta);
        mOutput2->changeRefCount(stream, delta);
    }
    if ((delta + (int)mRefCount[stream]) < 0) {
        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
              delta, stream, mRefCount[stream]);
@@ -124,15 +99,6 @@ void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
}

audio_devices_t AudioOutputDescriptor::supportedDevices()
{
    if (isDuplicated()) {
        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
    } else {
        return mProfile->mSupportedDevices.types() ;
    }
}

bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
{
    nsecs_t sysTime = 0;
@@ -169,12 +135,33 @@ bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
    return false;
}


bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
{
    return false;
}

bool AudioOutputDescriptor::setVolume(float volume,
                                      audio_stream_type_t stream,
                                      audio_devices_t device __unused,
                                      uint32_t delayMs,
                                      bool force)
{
    // We actually change the volume if:
    // - the float value returned by computeVolume() changed
    // - the force flag is set
    if (volume != mCurVolume[stream] || force) {
        ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
        mCurVolume[stream] = volume;
        return true;
    }
    return false;
}

void AudioOutputDescriptor::toAudioPortConfig(
                                                 struct audio_port_config *dstConfig,
                                                 const struct audio_port_config *srcConfig) const
{
    ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);

    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
                            AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
    if (srcConfig != NULL) {
@@ -186,21 +173,15 @@ void AudioOutputDescriptor::toAudioPortConfig(
    dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
    dstConfig->type = AUDIO_PORT_TYPE_MIX;
    dstConfig->ext.mix.hw_module = getModuleHandle();
    dstConfig->ext.mix.handle = mIoHandle;
    dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
}

void AudioOutputDescriptor::toAudioPort(
                                                    struct audio_port *port) const
{
    ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
    mProfile->toAudioPort(port);
    mPort->toAudioPort(port);
    port->id = mId;
    toAudioPortConfig(&port->active_config);
    port->ext.mix.hw_module = getModuleHandle();
    port->ext.mix.handle = mIoHandle;
    port->ext.mix.latency_class =
            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
}

status_t AudioOutputDescriptor::dump(int fd)
@@ -209,7 +190,7 @@ status_t AudioOutputDescriptor::dump(int fd)
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, " ID: %d\n", getId());
    snprintf(buffer, SIZE, " ID: %d\n", mId);
    result.append(buffer);
    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
    result.append(buffer);
@@ -217,10 +198,6 @@ status_t AudioOutputDescriptor::dump(int fd)
    result.append(buffer);
    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
    result.append(buffer);
    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
    result.append(buffer);
    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
    result.append(buffer);
    snprintf(buffer, SIZE, " Devices %08x\n", device());
    result.append(buffer);
    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
@@ -237,15 +214,162 @@ status_t AudioOutputDescriptor::dump(int fd)

void AudioOutputDescriptor::log(const char* indent)
{
    ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X] hndl:%d",
          indent, mId, mId, mSamplingRate, mFormat, mChannelMask, mIoHandle);
    ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
          indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
}

// SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor::SwAudioOutputDescriptor(
        const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface)
    : AudioOutputDescriptor(profile, clientInterface),
    mProfile(profile), mIoHandle(0), mLatency(0),
    mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
    mOutput1(0), mOutput2(0), mDirectOpenCount(0)
{
    if (profile != NULL) {
        mFlags = (audio_output_flags_t)profile->mFlags;
    }
}

void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
{
    mId = AudioPort::getNextUniqueId();
    mIoHandle = ioHandle;
}


status_t SwAudioOutputDescriptor::dump(int fd)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
    result.append(buffer);
    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
    result.append(buffer);
    write(fd, result.string(), result.size());

    AudioOutputDescriptor::dump(fd);

    return NO_ERROR;
}

audio_devices_t SwAudioOutputDescriptor::device() const
{
    if (isDuplicated()) {
        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
    } else {
        return mDevice;
    }
}

bool SwAudioOutputDescriptor::sharesHwModuleWith(
        const sp<AudioOutputDescriptor> outputDesc)
{
    if (isDuplicated()) {
        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
    } else if (outputDesc->isDuplicated()){
        return sharesHwModuleWith(outputDesc->subOutput1()) ||
                    sharesHwModuleWith(outputDesc->subOutput2());
    } else {
        return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
    }
}

audio_devices_t SwAudioOutputDescriptor::supportedDevices()
{
    if (isDuplicated()) {
        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
    } else {
        return mProfile->mSupportedDevices.types() ;
    }
}

uint32_t SwAudioOutputDescriptor::latency()
{
    if (isDuplicated()) {
        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
    } else {
        return mLatency;
    }
}

void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
                                                                   int delta)
{
    // forward usage count change to attached outputs
    if (isDuplicated()) {
        mOutput1->changeRefCount(stream, delta);
        mOutput2->changeRefCount(stream, delta);
    }
    AudioOutputDescriptor::changeRefCount(stream, delta);
}


bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
{
    // unit gain if rerouting to external policy
    if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
        if (mPolicyMix != NULL) {
            ALOGV("max gain when rerouting for output=%d", mIoHandle);
            return true;
        }
    }
    return false;
}

void SwAudioOutputDescriptor::toAudioPortConfig(
                                                 struct audio_port_config *dstConfig,
                                                 const struct audio_port_config *srcConfig) const
{

    ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
    AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);

    dstConfig->ext.mix.handle = mIoHandle;
}

void SwAudioOutputDescriptor::toAudioPort(
                                                    struct audio_port *port) const
{
    ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);

    AudioOutputDescriptor::toAudioPort(port);

    toAudioPortConfig(&port->active_config);
    port->ext.mix.handle = mIoHandle;
    port->ext.mix.latency_class =
            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
}

bool SwAudioOutputDescriptor::setVolume(float volume,
                                        audio_stream_type_t stream,
                                        audio_devices_t device,
                                        uint32_t delayMs,
                                        bool force)
{
    bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);

    if (changed) {
        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
        // enabled
        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
            mClientInterface->setStreamVolume(
                    AUDIO_STREAM_VOICE_CALL, mCurVolume[stream], mIoHandle, delayMs);
        }
        mClientInterface->setStreamVolume(stream, mCurVolume[stream], mIoHandle, delayMs);
    }
    return changed;
}

// SwAudioOutputCollection implementation

bool AudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
{
    nsecs_t sysTime = systemTime();
    for (size_t i = 0; i < this->size(); i++) {
        const sp<AudioOutputDescriptor> outputDesc = this->valueAt(i);
        const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
            return true;
        }
@@ -253,12 +377,12 @@ bool AudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t
    return false;
}

bool AudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
                                                   uint32_t inPastMs) const
{
    nsecs_t sysTime = systemTime();
    for (size_t i = 0; i < size(); i++) {
        const sp<AudioOutputDescriptor> outputDesc = valueAt(i);
        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
            // do not consider re routing (when the output is going to a dynamic policy)
@@ -271,10 +395,10 @@ bool AudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
    return false;
}

audio_io_handle_t AudioOutputCollection::getA2dpOutput() const
audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
{
    for (size_t i = 0; i < size(); i++) {
        sp<AudioOutputDescriptor> outputDesc = valueAt(i);
        sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
            return this->keyAt(i);
        }
@@ -282,10 +406,10 @@ audio_io_handle_t AudioOutputCollection::getA2dpOutput() const
    return 0;
}

sp<AudioOutputDescriptor> AudioOutputCollection::getPrimaryOutput() const
sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
{
    for (size_t i = 0; i < size(); i++) {
        const sp<AudioOutputDescriptor> outputDesc = valueAt(i);
        const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
        if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
            return outputDesc;
        }
@@ -293,9 +417,9 @@ sp<AudioOutputDescriptor> AudioOutputCollection::getPrimaryOutput() const
    return NULL;
}

sp<AudioOutputDescriptor> AudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
{
    sp<AudioOutputDescriptor> outputDesc = NULL;
    sp<SwAudioOutputDescriptor> outputDesc = NULL;
    for (size_t i = 0; i < size(); i++) {
        outputDesc = valueAt(i);
        if (outputDesc->getId() == id) {
@@ -305,14 +429,14 @@ sp<AudioOutputDescriptor> AudioOutputCollection::getOutputFromId(audio_port_hand
    return outputDesc;
}

bool AudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
{
    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
        if (s == (size_t) streamToIgnore) {
            continue;
        }
        for (size_t i = 0; i < size(); i++) {
            const sp<AudioOutputDescriptor> outputDesc = valueAt(i);
            const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
            if (outputDesc->mRefCount[s] != 0) {
                return true;
            }
@@ -321,15 +445,15 @@ bool AudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore
    return false;
}

audio_devices_t AudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
{
    sp<AudioOutputDescriptor> outputDesc = valueFor(handle);
    sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
    audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types();
    return devices;
}


status_t AudioOutputCollection::dump(int fd) const
status_t SwAudioOutputCollection::dump(int fd) const
{
    const size_t SIZE = 256;
    char buffer[SIZE];
+4 −4
Original line number Diff line number Diff line
@@ -26,12 +26,12 @@

namespace android {

void AudioPolicyMix::setOutput(sp<AudioOutputDescriptor> &output)
void AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output)
{
    mOutput = output;
}

const sp<AudioOutputDescriptor> &AudioPolicyMix::getOutput() const
const sp<SwAudioOutputDescriptor> &AudioPolicyMix::getOutput() const
{
    return mOutput;
}
@@ -88,7 +88,7 @@ status_t AudioPolicyMixCollection::getAudioPolicyMix(String8 address,
    return NO_ERROR;
}

void AudioPolicyMixCollection::closeOutput(sp<AudioOutputDescriptor> &desc)
void AudioPolicyMixCollection::closeOutput(sp<SwAudioOutputDescriptor> &desc)
{
    for (size_t i = 0; i < size(); i++) {
        sp<AudioPolicyMix> policyMix = valueAt(i);
@@ -99,7 +99,7 @@ void AudioPolicyMixCollection::closeOutput(sp<AudioOutputDescriptor> &desc)
}

status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attributes,
                                                    sp<AudioOutputDescriptor> &desc)
                                                    sp<SwAudioOutputDescriptor> &desc)
{
    for (size_t i = 0; i < size(); i++) {
        sp<AudioPolicyMix> policyMix = valueAt(i);
Loading