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

Commit 4c1ef4b6 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio policy: concurrent capture

Implement concurrent capture in audio policy manager:
- Attach AudioRecord client to already opened input when possible
instead of systematically opening a new input for each client.
- Always allow inputs to start even in case of concurrency.
- Clients are selectively silenced based on their app state by audio
policy service.
- In case of concurrency on a given input stream, device and source is
chosen based app states and source priority.

Bug: 111438757
Test: Manual capture tests with solotester and Camera, Assistant and Duo
Test: CTS tests for AudioRecord

Change-Id: I302710ff545f67361d9aca89e81de40771ce7fb0
parent 973db02a
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -917,11 +917,11 @@ status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
            config, flags, selectedDeviceId, portId);
            config, flags, selectedDeviceId, portId);
}
}


status_t AudioSystem::startInput(audio_port_handle_t portId, bool *silenced)
status_t AudioSystem::startInput(audio_port_handle_t portId)
{
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;
    if (aps == 0) return PERMISSION_DENIED;
    return aps->startInput(portId, silenced);
    return aps->startInput(portId);
}
}


status_t AudioSystem::stopInput(audio_port_handle_t portId)
status_t AudioSystem::stopInput(audio_port_handle_t portId)
+2 −7
Original line number Original line Diff line number Diff line
@@ -329,16 +329,13 @@ public:
        return NO_ERROR;
        return NO_ERROR;
    }
    }


    virtual status_t startInput(audio_port_handle_t portId,
    virtual status_t startInput(audio_port_handle_t portId)
                                bool *silenced)
    {
    {
        Parcel data, reply;
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(portId);
        data.writeInt32(portId);
        data.writeInt32(*silenced ? 1 : 0);
        remote()->transact(START_INPUT, data, &reply);
        remote()->transact(START_INPUT, data, &reply);
        status_t status = static_cast <status_t> (reply.readInt32());
        status_t status = static_cast <status_t> (reply.readInt32());
        *silenced = reply.readInt32() == 1;
        return status;
        return status;
    }
    }


@@ -1219,10 +1216,8 @@ status_t BnAudioPolicyService::onTransact(
        case START_INPUT: {
        case START_INPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            bool silenced = data.readInt32() == 1;
            status_t status = startInput(portId);
            status_t status = startInput(portId, &silenced);
            reply->writeInt32(static_cast <uint32_t>(status));
            reply->writeInt32(static_cast <uint32_t>(status));
            reply->writeInt32(silenced ? 1 : 0);
            return NO_ERROR;
            return NO_ERROR;
        } break;
        } break;


+1 −2
Original line number Original line Diff line number Diff line
@@ -241,8 +241,7 @@ public:
                                    audio_port_handle_t *selectedDeviceId,
                                    audio_port_handle_t *selectedDeviceId,
                                    audio_port_handle_t *portId);
                                    audio_port_handle_t *portId);


    static status_t startInput(audio_port_handle_t portId,
    static status_t startInput(audio_port_handle_t portId);
                               bool *silenced);
    static status_t stopInput(audio_port_handle_t portId);
    static status_t stopInput(audio_port_handle_t portId);
    static void releaseInput(audio_port_handle_t portId);
    static void releaseInput(audio_port_handle_t portId);
    static status_t initStreamVolume(audio_stream_type_t stream,
    static status_t initStreamVolume(audio_stream_type_t stream,
+1 −2
Original line number Original line Diff line number Diff line
@@ -78,8 +78,7 @@ public:
                              audio_input_flags_t flags,
                              audio_input_flags_t flags,
                              audio_port_handle_t *selectedDeviceId,
                              audio_port_handle_t *selectedDeviceId,
                              audio_port_handle_t *portId) = 0;
                              audio_port_handle_t *portId) = 0;
    virtual status_t startInput(audio_port_handle_t portId,
    virtual status_t startInput(audio_port_handle_t portId) = 0;
                                bool *silenced) = 0;
    virtual status_t stopInput(audio_port_handle_t portId) = 0;
    virtual status_t stopInput(audio_port_handle_t portId) = 0;
    virtual void releaseInput(audio_port_handle_t portId) = 0;
    virtual void releaseInput(audio_port_handle_t portId) = 0;
    virtual status_t initStreamVolume(audio_stream_type_t stream,
    virtual status_t initStreamVolume(audio_stream_type_t stream,
+10 −13
Original line number Original line Diff line number Diff line
@@ -7367,8 +7367,7 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac
        status_t status = NO_ERROR;
        status_t status = NO_ERROR;
        if (recordTrack->isExternalTrack()) {
        if (recordTrack->isExternalTrack()) {
            mLock.unlock();
            mLock.unlock();
            bool silenced;
            status = AudioSystem::startInput(recordTrack->portId());
            status = AudioSystem::startInput(recordTrack->portId(), &silenced);
            mLock.lock();
            mLock.lock();
            if (recordTrack->isInvalid()) {
            if (recordTrack->isInvalid()) {
                recordTrack->clearSyncStartEvent();
                recordTrack->clearSyncStartEvent();
@@ -7396,7 +7395,6 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac
                recordTrack->clearSyncStartEvent();
                recordTrack->clearSyncStartEvent();
                return status;
                return status;
            }
            }
            recordTrack->setSilenced(silenced);
        }
        }
        // Catch up with current buffer indices if thread is already running.
        // Catch up with current buffer indices if thread is already running.
        // This is what makes a new client discard all buffered data.  If the track's mRsmpInFront
        // This is what makes a new client discard all buffered data.  If the track's mRsmpInFront
@@ -8346,11 +8344,10 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    bool silenced = false;
    if (isOutput()) {
    if (isOutput()) {
        ret = AudioSystem::startOutput(portId);
        ret = AudioSystem::startOutput(portId);
    } else {
    } else {
        ret = AudioSystem::startInput(portId, &silenced);
        ret = AudioSystem::startInput(portId);
    }
    }


    Mutex::Autolock _l(mLock);
    Mutex::Autolock _l(mLock);
@@ -8371,21 +8368,21 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
        return PERMISSION_DENIED;
        return PERMISSION_DENIED;
    }
    }


    // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
    sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
                                        isOutput(), client.clientUid, client.clientPid, portId);

    if (isOutput()) {
    if (isOutput()) {
        // force volume update when a new track is added
        // force volume update when a new track is added
        mHalVolFloat = -1.0f;
        mHalVolFloat = -1.0f;
    } else if (!silenced) {
    } else if (!track->isSilenced_l()) {
        for (const sp<MmapTrack> &track : mActiveTracks) {
        for (const sp<MmapTrack> &t : mActiveTracks) {
            if (track->isSilenced_l() && track->uid() != client.clientUid)
            if (t->isSilenced_l() && t->uid() != client.clientUid)
                track->invalidate();
                t->invalidate();
        }
        }
    }
    }


    // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
    sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
                                        isOutput(), client.clientUid, client.clientPid, portId);


    track->setSilenced_l(silenced);
    mActiveTracks.add(track);
    mActiveTracks.add(track);
    sp<EffectChain> chain = getEffectChain_l(mSessionId);
    sp<EffectChain> chain = getEffectChain_l(mSessionId);
    if (chain != 0) {
    if (chain != 0) {
Loading