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

Commit 55b2a0fd authored by Francois Gaffie's avatar Francois Gaffie Committed by Eric Laurent
Browse files

AudioFlinger: Control volume using Port ID

This CL migrates the volume management within AudioFlinger
from stream type to port ID.

It gives full power to AudioPolicy to compute the list of port
(so MmapThreads/Tracks) on which volume control is required.

It prevents from overwritting MUSIC stream type which is
the default for volume groups without associated stream type.

Bug: 317212590
Test: build & play audio
Test: atest audiopolicy_tests
Flag: com.android.media.audioserver.portid_volume_management

Change-Id: I4c9e8bb45660c9ceffcc0f4029b0617f9795ab3c
parent 99987f57
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -322,6 +322,26 @@ status_t AudioSystem::setStreamMute(audio_stream_type_t stream, bool mute) {
    return NO_ERROR;
}

status_t AudioSystem::setPortsVolume(
        const std::vector<audio_port_handle_t>& portIds, float volume, audio_io_handle_t output) {
    for (const auto& port : portIds) {
        if (port == AUDIO_PORT_HANDLE_NONE) {
            return BAD_VALUE;
        }
    }
    if (isnan(volume) || volume > 1.0f || volume < 0.0f) {
        return BAD_VALUE;
    }
    const sp<IAudioFlinger> af = get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
    std::vector<int32_t> portIdsAidl = VALUE_OR_RETURN_STATUS(
            convertContainer<std::vector<int32_t>>(
                    portIds, legacy2aidl_audio_port_handle_t_int32_t));
    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
    af->setPortsVolume(portIdsAidl, volume, outputAidl);
    return NO_ERROR;
}

status_t AudioSystem::setMode(audio_mode_t mode) {
    if (uint32_t(mode) >= AUDIO_MODE_CNT) return BAD_VALUE;
    const sp<IAudioFlinger> af = get_audio_flinger();
@@ -1081,7 +1101,8 @@ status_t AudioSystem::getOutputForAttr(audio_attributes_t* attr,
                                       audio_port_handle_t* portId,
                                       std::vector<audio_io_handle_t>* secondaryOutputs,
                                       bool *isSpatialized,
                                       bool *isBitPerfect) {
                                       bool *isBitPerfect,
                                       float *volume) {
    if (attr == nullptr) {
        ALOGE("%s NULL audio attributes", __func__);
        return BAD_VALUE;
@@ -1147,6 +1168,7 @@ status_t AudioSystem::getOutputForAttr(audio_attributes_t* attr,
    *isBitPerfect = responseAidl.isBitPerfect;
    *attr = VALUE_OR_RETURN_STATUS(
            aidl2legacy_AudioAttributes_audio_attributes_t(responseAidl.attr));
    *volume = responseAidl.volume;

    return OK;
}
+19 −0
Original line number Diff line number Diff line
@@ -350,6 +350,15 @@ status_t AudioFlingerClientAdapter::setStreamMute(audio_stream_type_t stream, bo
    return statusTFromBinderStatus(mDelegate->setStreamMute(streamAidl, muted));
}

status_t AudioFlingerClientAdapter::setPortsVolume(
        const std::vector<audio_port_handle_t>& portIds, float volume, audio_io_handle_t output) {
    std::vector<int32_t> portIdsAidl = VALUE_OR_RETURN_STATUS(
            convertContainer<std::vector<int32_t>>(
                    portIds, legacy2aidl_audio_port_handle_t_int32_t));
    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
    return statusTFromBinderStatus(mDelegate->setPortsVolume(portIdsAidl, volume, outputAidl));
}

status_t AudioFlingerClientAdapter::setMode(audio_mode_t mode) {
    AudioMode modeAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_mode_t_AudioMode(mode));
    return statusTFromBinderStatus(mDelegate->setMode(modeAidl));
@@ -1012,6 +1021,16 @@ Status AudioFlingerServerAdapter::setStreamMute(AudioStreamType stream, bool mut
    return Status::fromStatusT(mDelegate->setStreamMute(streamLegacy, muted));
}

Status AudioFlingerServerAdapter::setPortsVolume(
        const std::vector<int32_t>& portIds, float volume, int32_t output) {
    std::vector<audio_port_handle_t> portIdsLegacy = VALUE_OR_RETURN_BINDER(
            convertContainer<std::vector<audio_port_handle_t>>(
                    portIds, aidl2legacy_int32_t_audio_port_handle_t));
    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
            aidl2legacy_int32_t_audio_io_handle_t(output));
    return Status::fromStatusT(mDelegate->setPortsVolume(portIdsLegacy, volume, outputLegacy));
}

Status AudioFlingerServerAdapter::setMode(AudioMode mode) {
    audio_mode_t modeLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioMode_audio_mode_t(mode));
    return Status::fromStatusT(mDelegate->setMode(modeLegacy));
+2 −0
Original line number Diff line number Diff line
@@ -39,4 +39,6 @@ parcelable GetOutputForAttrResponse {
    boolean isBitPerfect;
    /** The corrected audio attributes. **/
    AudioAttributes attr;
    /** initial port volume for the new audio track */
    float volume;
}
+7 −0
Original line number Diff line number Diff line
@@ -100,6 +100,13 @@ interface IAudioFlingerService {
    void setStreamVolume(AudioStreamType stream, float value, int /* audio_io_handle_t */ output);
    void setStreamMute(AudioStreamType stream, boolean muted);

    /*
     * Set AudioTrack port ids volume attribute. This is the new way of controlling volume from
     * AudioPolicyManager to AudioFlinger.
     */
    void setPortsVolume(in int[] /* audio_port_handle_t[] */ portIds, float volume,
            int /* audio_io_handle_t */ output);

    // set audio mode.
    void setMode(AudioMode mode);

+16 −7
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <android/content/AttributionSourceState.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryDealer.h>
#include <com_android_media_audioserver.h>
#include <media/AidlConversion.h>
#include <media/AudioEffect.h>
#include <media/AudioRecord.h>
@@ -41,6 +42,8 @@ constexpr int32_t kMinSampleRateHz = 4000;
constexpr int32_t kMaxSampleRateHz = 192000;
constexpr int32_t kSampleRateUnspecified = 0;

namespace audioserver_flags = com::android::media::audioserver;

using namespace std;
using namespace android;

@@ -501,13 +504,19 @@ void AudioFlingerFuzzer::invokeAudioSystem() {
    AudioSystem::getMasterMute(&state);
    AudioSystem::isMicrophoneMuted(&state);

    audio_stream_type_t stream = getValue(&mFdp, kStreamtypes);
    audio_stream_type_t stream ;
    if (!audioserver_flags::portid_volume_management()) {
        stream = getValue(&mFdp, kStreamtypes);
        AudioSystem::setStreamMute(getValue(&mFdp, kStreamtypes), mFdp.ConsumeBool());

        stream = getValue(&mFdp, kStreamtypes);
        AudioSystem::setStreamVolume(stream, mFdp.ConsumeFloatingPoint<float>(),
                                     mFdp.ConsumeIntegral<int32_t>());

    } else {
        std::vector <audio_port_handle_t> portsForVolumeChange{};
        AudioSystem::setPortsVolume(portsForVolumeChange, mFdp.ConsumeFloatingPoint<float>(),
                                    mFdp.ConsumeIntegral<int32_t>());
    }
    audio_mode_t mode = getValue(&mFdp, kModes);
    AudioSystem::setMode(mode);

Loading