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

Commit 5385847f authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Move business logic out of IAudioFlinger

IAudioFlinger should only contain transport logic, in preparation for
AIDL conversion.

Test: Audio-related CTS tests from CtsMediaTestCases
Change-Id: I2a6d8f16da720a3db7c673e5b2bb9bbd23bbf985
parent f9dd9246
Loading
Loading
Loading
Loading
+0 −179
Original line number Diff line number Diff line
@@ -24,77 +24,10 @@

#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <media/AudioValidator.h>
#include <media/IAudioPolicyService.h>
#include <mediautils/ServiceUtilities.h>
#include <mediautils/TimeCheck.h>
#include "IAudioFlinger.h"

namespace android {

enum {
    CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
    CREATE_RECORD,
    SAMPLE_RATE,
    RESERVED,   // obsolete, was CHANNEL_COUNT
    FORMAT,
    FRAME_COUNT,
    LATENCY,
    SET_MASTER_VOLUME,
    SET_MASTER_MUTE,
    MASTER_VOLUME,
    MASTER_MUTE,
    SET_STREAM_VOLUME,
    SET_STREAM_MUTE,
    STREAM_VOLUME,
    STREAM_MUTE,
    SET_MODE,
    SET_MIC_MUTE,
    GET_MIC_MUTE,
    SET_RECORD_SILENCED,
    SET_PARAMETERS,
    GET_PARAMETERS,
    REGISTER_CLIENT,
    GET_INPUTBUFFERSIZE,
    OPEN_OUTPUT,
    OPEN_DUPLICATE_OUTPUT,
    CLOSE_OUTPUT,
    SUSPEND_OUTPUT,
    RESTORE_OUTPUT,
    OPEN_INPUT,
    CLOSE_INPUT,
    INVALIDATE_STREAM,
    SET_VOICE_VOLUME,
    GET_RENDER_POSITION,
    GET_INPUT_FRAMES_LOST,
    NEW_AUDIO_UNIQUE_ID,
    ACQUIRE_AUDIO_SESSION_ID,
    RELEASE_AUDIO_SESSION_ID,
    QUERY_NUM_EFFECTS,
    QUERY_EFFECT,
    GET_EFFECT_DESCRIPTOR,
    CREATE_EFFECT,
    MOVE_EFFECTS,
    LOAD_HW_MODULE,
    GET_PRIMARY_OUTPUT_SAMPLING_RATE,
    GET_PRIMARY_OUTPUT_FRAME_COUNT,
    SET_LOW_RAM_DEVICE,
    LIST_AUDIO_PORTS,
    GET_AUDIO_PORT,
    CREATE_AUDIO_PATCH,
    RELEASE_AUDIO_PATCH,
    LIST_AUDIO_PATCHES,
    SET_AUDIO_PORT_CONFIG,
    GET_AUDIO_HW_SYNC_FOR_SESSION,
    SYSTEM_READY,
    FRAME_COUNT_HAL,
    GET_MICROPHONES,
    SET_MASTER_BALANCE,
    GET_MASTER_BALANCE,
    SET_EFFECT_SUSPENDED,
    SET_AUDIO_HAL_PIDS
};

#define MAX_ITEMS_PER_LIST 1024

ConversionResult<media::CreateTrackRequest> IAudioFlinger::CreateTrackInput::toAidl() const {
@@ -988,106 +921,6 @@ IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
status_t BnAudioFlinger::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // make sure transactions reserved to AudioPolicyManager do not come from other processes
    switch (code) {
        case SET_STREAM_VOLUME:
        case SET_STREAM_MUTE:
        case OPEN_OUTPUT:
        case OPEN_DUPLICATE_OUTPUT:
        case CLOSE_OUTPUT:
        case SUSPEND_OUTPUT:
        case RESTORE_OUTPUT:
        case OPEN_INPUT:
        case CLOSE_INPUT:
        case INVALIDATE_STREAM:
        case SET_VOICE_VOLUME:
        case MOVE_EFFECTS:
        case SET_EFFECT_SUSPENDED:
        case LOAD_HW_MODULE:
        case LIST_AUDIO_PORTS:
        case GET_AUDIO_PORT:
        case CREATE_AUDIO_PATCH:
        case RELEASE_AUDIO_PATCH:
        case LIST_AUDIO_PATCHES:
        case SET_AUDIO_PORT_CONFIG:
        case SET_RECORD_SILENCED:
            ALOGW("%s: transaction %d received from PID %d",
                  __func__, code, IPCThreadState::self()->getCallingPid());
            // return status only for non void methods
            switch (code) {
                case SET_RECORD_SILENCED:
                case SET_EFFECT_SUSPENDED:
                    break;
                default:
                    reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
                    break;
            }
            return OK;
        default:
            break;
    }

    // make sure the following transactions come from system components
    switch (code) {
        case SET_MASTER_VOLUME:
        case SET_MASTER_MUTE:
        case SET_MODE:
        case SET_MIC_MUTE:
        case SET_LOW_RAM_DEVICE:
        case SYSTEM_READY:
        case SET_AUDIO_HAL_PIDS: {
            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                      __func__, code, IPCThreadState::self()->getCallingPid(),
                      IPCThreadState::self()->getCallingUid());
                // return status only for non void methods
                switch (code) {
                    case SYSTEM_READY:
                        break;
                    default:
                        reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
                        break;
                }
                return OK;
            }
        } break;
        default:
            break;
    }

    // List of relevant events that trigger log merging.
    // Log merging should activate during audio activity of any kind. This are considered the
    // most relevant events.
    // TODO should select more wisely the items from the list
    switch (code) {
        case CREATE_TRACK:
        case CREATE_RECORD:
        case SET_MASTER_VOLUME:
        case SET_MASTER_MUTE:
        case SET_MIC_MUTE:
        case SET_PARAMETERS:
        case CREATE_EFFECT:
        case SYSTEM_READY: {
            requestLogMerge();
            break;
        }
        default:
            break;
    }

    std::string tag("IAudioFlinger command " + std::to_string(code));
    TimeCheck check(tag.c_str());

    // Make sure we connect to Audio Policy Service before calling into AudioFlinger:
    //  - AudioFlinger can call into Audio Policy Service with its global mutex held
    //  - If this is the first time Audio Policy Service is queried from inside audioserver process
    //  this will trigger Audio Policy Manager initialization.
    //  - Audio Policy Manager initialization calls into AudioFlinger which will try to lock
    //  its global mutex and a deadlock will occur.
    if (IPCThreadState::self()->getCallingPid() != getpid()) {
        AudioSystem::get_audio_policy_service();
    }

    switch (code) {
        case CREATE_TRACK: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
@@ -1496,10 +1329,6 @@ status_t BnAudioFlinger::onTransact(
                ALOGE("b/23905951");
                return status;
            }
            status = AudioValidator::validateAudioPort(port);
            if (status == NO_ERROR) {
                status = getAudioPort(&port);
            }
            reply->writeInt32(status);
            if (status == NO_ERROR) {
                reply->write(&port, sizeof(struct audio_port_v7));
@@ -1519,10 +1348,6 @@ status_t BnAudioFlinger::onTransact(
                ALOGE("b/23905951");
                return status;
            }
            status = AudioValidator::validateAudioPatch(patch);
            if (status == NO_ERROR) {
                status = createAudioPatch(&patch, &handle);
            }
            reply->writeInt32(status);
            if (status == NO_ERROR) {
                reply->write(&handle, sizeof(audio_patch_handle_t));
@@ -1571,10 +1396,6 @@ status_t BnAudioFlinger::onTransact(
            if (status != NO_ERROR) {
                return status;
            }
            status = AudioValidator::validateAudioPortConfig(config);
            if (status == NO_ERROR) {
                status = setAudioPortConfig(&config);
            }
            reply->writeInt32(status);
            return NO_ERROR;
        } break;
+64 −3
Original line number Diff line number Diff line
@@ -333,6 +333,70 @@ public:
    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;

    virtual status_t setAudioHalPids(const std::vector<pid_t>& pids) = 0;

protected:
    enum {
        CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
        CREATE_RECORD,
        SAMPLE_RATE,
        RESERVED,   // obsolete, was CHANNEL_COUNT
        FORMAT,
        FRAME_COUNT,
        LATENCY,
        SET_MASTER_VOLUME,
        SET_MASTER_MUTE,
        MASTER_VOLUME,
        MASTER_MUTE,
        SET_STREAM_VOLUME,
        SET_STREAM_MUTE,
        STREAM_VOLUME,
        STREAM_MUTE,
        SET_MODE,
        SET_MIC_MUTE,
        GET_MIC_MUTE,
        SET_RECORD_SILENCED,
        SET_PARAMETERS,
        GET_PARAMETERS,
        REGISTER_CLIENT,
        GET_INPUTBUFFERSIZE,
        OPEN_OUTPUT,
        OPEN_DUPLICATE_OUTPUT,
        CLOSE_OUTPUT,
        SUSPEND_OUTPUT,
        RESTORE_OUTPUT,
        OPEN_INPUT,
        CLOSE_INPUT,
        INVALIDATE_STREAM,
        SET_VOICE_VOLUME,
        GET_RENDER_POSITION,
        GET_INPUT_FRAMES_LOST,
        NEW_AUDIO_UNIQUE_ID,
        ACQUIRE_AUDIO_SESSION_ID,
        RELEASE_AUDIO_SESSION_ID,
        QUERY_NUM_EFFECTS,
        QUERY_EFFECT,
        GET_EFFECT_DESCRIPTOR,
        CREATE_EFFECT,
        MOVE_EFFECTS,
        LOAD_HW_MODULE,
        GET_PRIMARY_OUTPUT_SAMPLING_RATE,
        GET_PRIMARY_OUTPUT_FRAME_COUNT,
        SET_LOW_RAM_DEVICE,
        LIST_AUDIO_PORTS,
        GET_AUDIO_PORT,
        CREATE_AUDIO_PATCH,
        RELEASE_AUDIO_PATCH,
        LIST_AUDIO_PATCHES,
        SET_AUDIO_PORT_CONFIG,
        GET_AUDIO_HW_SYNC_FOR_SESSION,
        SYSTEM_READY,
        FRAME_COUNT_HAL,
        GET_MICROPHONES,
        SET_MASTER_BALANCE,
        GET_MASTER_BALANCE,
        SET_EFFECT_SUSPENDED,
        SET_AUDIO_HAL_PIDS
    };
};


@@ -345,9 +409,6 @@ public:
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

    // Requests media.log to start merging log buffers
    virtual void requestLogMerge() = 0;
};

// ----------------------------------------------------------------------------
+109 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <sys/resource.h>
#include <thread>


#include <android/os/IExternalVibratorService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -41,8 +42,10 @@
#include <media/audiohal/DevicesFactoryHalInterface.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <media/AudioParameter.h>
#include <media/IAudioPolicyService.h>
#include <media/MediaMetricsItem.h>
#include <media/TypeConverter.h>
#include <mediautils/TimeCheck.h>
#include <memunreachable/memunreachable.h>
#include <utils/String16.h>
#include <utils/threads.h>
@@ -69,6 +72,7 @@

#include <media/IMediaLogService.h>
#include <media/AidlConversion.h>
#include <media/AudioValidator.h>
#include <media/nbaio/Pipe.h>
#include <media/nbaio/PipeReader.h>
#include <mediautils/BatteryNotifier.h>
@@ -2335,6 +2339,11 @@ status_t AudioFlinger::setAudioPortConfig(const struct audio_port_config *config
{
    ALOGV(__func__);

    status_t status = AudioValidator::validateAudioPortConfig(*config);
    if (status != NO_ERROR) {
        return status;
    }

    audio_module_handle_t module;
    if (config->type == AUDIO_PORT_TYPE_DEVICE) {
        module = config->ext.device.hw_module;
@@ -4036,6 +4045,106 @@ bool AudioFlinger::updateOrphanEffectChains(const sp<AudioFlinger::EffectModule>
status_t AudioFlinger::onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // make sure transactions reserved to AudioPolicyManager do not come from other processes
    switch (code) {
        case SET_STREAM_VOLUME:
        case SET_STREAM_MUTE:
        case OPEN_OUTPUT:
        case OPEN_DUPLICATE_OUTPUT:
        case CLOSE_OUTPUT:
        case SUSPEND_OUTPUT:
        case RESTORE_OUTPUT:
        case OPEN_INPUT:
        case CLOSE_INPUT:
        case INVALIDATE_STREAM:
        case SET_VOICE_VOLUME:
        case MOVE_EFFECTS:
        case SET_EFFECT_SUSPENDED:
        case LOAD_HW_MODULE:
        case LIST_AUDIO_PORTS:
        case GET_AUDIO_PORT:
        case CREATE_AUDIO_PATCH:
        case RELEASE_AUDIO_PATCH:
        case LIST_AUDIO_PATCHES:
        case SET_AUDIO_PORT_CONFIG:
        case SET_RECORD_SILENCED:
            ALOGW("%s: transaction %d received from PID %d",
                  __func__, code, IPCThreadState::self()->getCallingPid());
            // return status only for non void methods
            switch (code) {
                case SET_RECORD_SILENCED:
                case SET_EFFECT_SUSPENDED:
                    break;
                default:
                    reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
                    break;
            }
            return OK;
        default:
            break;
    }

    // make sure the following transactions come from system components
    switch (code) {
        case SET_MASTER_VOLUME:
        case SET_MASTER_MUTE:
        case SET_MODE:
        case SET_MIC_MUTE:
        case SET_LOW_RAM_DEVICE:
        case SYSTEM_READY:
        case SET_AUDIO_HAL_PIDS: {
            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                      __func__, code, IPCThreadState::self()->getCallingPid(),
                      IPCThreadState::self()->getCallingUid());
                // return status only for non void methods
                switch (code) {
                    case SYSTEM_READY:
                        break;
                    default:
                        reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
                        break;
                }
                return OK;
            }
        } break;
        default:
            break;
    }

    // List of relevant events that trigger log merging.
    // Log merging should activate during audio activity of any kind. This are considered the
    // most relevant events.
    // TODO should select more wisely the items from the list
    switch (code) {
        case CREATE_TRACK:
        case CREATE_RECORD:
        case SET_MASTER_VOLUME:
        case SET_MASTER_MUTE:
        case SET_MIC_MUTE:
        case SET_PARAMETERS:
        case CREATE_EFFECT:
        case SYSTEM_READY: {
            requestLogMerge();
            break;
        }
        default:
            break;
    }

    std::string tag("IAudioFlinger command " + std::to_string(code));
    TimeCheck check(tag.c_str());

    // Make sure we connect to Audio Policy Service before calling into AudioFlinger:
    //  - AudioFlinger can call into Audio Policy Service with its global mutex held
    //  - If this is the first time Audio Policy Service is queried from inside audioserver process
    //  this will trigger Audio Policy Manager initialization.
    //  - Audio Policy Manager initialization calls into AudioFlinger which will try to lock
    //  its global mutex and a deadlock will occur.
    if (IPCThreadState::self()->getCallingPid() != getpid()) {
        AudioSystem::get_audio_policy_service();
    }

    return BnAudioFlinger::onTransact(code, data, reply, flags);
}

+1 −0
Original line number Diff line number Diff line
@@ -519,6 +519,7 @@ private:
    const sp<MediaLogNotifier> mMediaLogNotifier;

    // This is a helper that is called during incoming binder calls.
    // Requests media.log to start merging log buffers
    void requestLogMerge();

    class TrackHandle;
+11 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include "AudioFlinger.h"
#include <media/AudioParameter.h>
#include <media/AudioValidator.h>
#include <media/DeviceDescriptorBase.h>
#include <media/PatchBuilder.h>
#include <mediautils/ServiceUtilities.h>
@@ -56,6 +57,11 @@ status_t AudioFlinger::listAudioPorts(unsigned int *num_ports,

/* Get supported attributes for a given audio port */
status_t AudioFlinger::getAudioPort(struct audio_port_v7 *port) {
    status_t status = AudioValidator::validateAudioPort(*port);
    if (status != NO_ERROR) {
        return status;
    }

    Mutex::Autolock _l(mLock);
    return mPatchPanel.getAudioPort(port);
}
@@ -64,6 +70,11 @@ status_t AudioFlinger::getAudioPort(struct audio_port_v7 *port) {
status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
                                   audio_patch_handle_t *handle)
{
    status_t status = AudioValidator::validateAudioPatch(*patch);
    if (status != NO_ERROR) {
        return status;
    }

    Mutex::Autolock _l(mLock);
    return mPatchPanel.createAudioPatch(patch, handle);
}