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

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

audio policy: add support for external audio sources

Add support for activity on external audio sources.
An external source reflects activity on an input audio device
that must be controlled (both routing and volume) by the
audio policy manager.
First, the input device must be connected with setDeviceConnectionState().
Then, the source activity is indicated with startAudioSource() and
stopAudioSource() APIs.
startAudioSource() indicates the source device with an audio port configuration
and the use case by the audio attributes.

Once a source is active, its routing and volume are controlled by the policy manager
as it would for a software source (AudioTrack).

Change-Id: If5805d58a4356b2f681f1aabf54375f62b55b98a
parent 0443ba44
Loading
Loading
Loading
Loading
+18 −13
Original line number Diff line number Diff line
@@ -152,7 +152,8 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
        return BAD_VALUE;
    }
    if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
            patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
            (patch->num_sinks == 0 && patch->num_sources != 2) ||
            patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
        return BAD_VALUE;
    }
    // limit number of sources to 1 for now or 2 sources for special cross hw module case.
@@ -203,18 +204,18 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
            }

            // manage patches requiring a software bridge
            // - special patch request with 2 sources (reuse one existing output mix) OR
            // - Device to device AND
            //    - source HW module != destination HW module OR
            //    - audio HAL version < 3.0
            //    - special patch request with 2 sources (reuse one existing output mix)
            if ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
            if ((patch->num_sources == 2) ||
                ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
                 ((patch->sinks[0].ext.device.hw_module != srcModule) ||
                    (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) ||
                    (patch->num_sources == 2))) {
                  (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0)))) {
                if (patch->num_sources == 2) {
                    if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
                            patch->sinks[0].ext.device.hw_module !=
                                    patch->sources[1].ext.mix.hw_module) {
                            (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
                                    patch->sources[1].ext.mix.hw_module)) {
                        ALOGW("createAudioPatch() invalid source combination");
                        status = INVALID_OPERATION;
                        goto exit;
@@ -379,6 +380,7 @@ status_t AudioFlinger::PatchPanel::createPatchConnections(Patch *patch,
    }

    // create patch from playback thread output to sink device
    if (audioPatch->num_sinks != 0) {
        patch->mPlaybackThread->getAudioPortConfig(&subPatch.sources[0]);
        subPatch.sinks[0] = audioPatch->sinks[0];
        status = createAudioPatch(&subPatch, &patch->mPlaybackPatchHandle);
@@ -386,6 +388,9 @@ status_t AudioFlinger::PatchPanel::createPatchConnections(Patch *patch,
            patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
            return status;
        }
    } else {
        patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
    }

    // use a pseudo LCM between input and output framecount
    size_t playbackFrameCount = patch->mPlaybackThread->frameCount();
+1 −1
Original line number Diff line number Diff line
@@ -2548,7 +2548,7 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy
    size_t size = mTracks.size();
    for (size_t i = 0; i < size; i++) {
        sp<Track> t = mTracks[i];
        if (t->streamType() == streamType) {
        if (t->streamType() == streamType && t->isExternalTrack()) {
            t->invalidate();
        }
    }
+2 −1
Original line number Diff line number Diff line
@@ -225,7 +225,8 @@ public:

    virtual status_t startAudioSource(const struct audio_port_config *source,
                                      const audio_attributes_t *attributes,
                                      audio_io_handle_t *handle) = 0;
                                      audio_io_handle_t *handle,
                                      uid_t uid) = 0;
    virtual status_t stopAudioSource(audio_io_handle_t handle) = 0;
};

+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ LOCAL_SRC_FILES:= \
    src/ConfigParsingUtils.cpp \
    src/SoundTriggerSession.cpp \
    src/SessionRoute.cpp \
    src/AudioSourceDescriptor.cpp

LOCAL_SHARED_LIBRARIES := \
    libcutils \
+42 −0
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@
#include <utils/Timers.h>
#include <utils/KeyedVector.h>
#include <system/audio.h>
#include "AudioSourceDescriptor.h"

namespace android {

class IOProfile;
class AudioMix;
class AudioPolicyClientInterface;
class DeviceDescriptor;

// 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.
@@ -126,6 +128,31 @@ public:
    uint32_t mGlobalRefCount;  // non-stream-specific ref count
};

// Audio output driven by an input device directly.
class HwAudioOutputDescriptor: public AudioOutputDescriptor
{
public:
    HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
                            AudioPolicyClientInterface *clientInterface);
    virtual ~HwAudioOutputDescriptor() {}

    status_t    dump(int fd);

    virtual audio_devices_t supportedDevices();
    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<AudioSourceDescriptor> mSource;

};

class SwAudioOutputCollection :
        public DefaultKeyedVector< audio_io_handle_t, sp<SwAudioOutputDescriptor> >
{
@@ -160,4 +187,19 @@ public:
    status_t dump(int fd) const;
};

class HwAudioOutputCollection :
        public DefaultKeyedVector< audio_io_handle_t, sp<HwAudioOutputDescriptor> >
{
public:
    bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;

    /**
     * return true if any output is playing anything besides the stream to ignore
     */
    bool isAnyOutputActive(audio_stream_type_t streamToIgnore) const;

    status_t dump(int fd) const;
};


}; // namespace android
Loading