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

Commit de8d0e43 authored by Steve Kondik's avatar Steve Kondik Committed by Bruno Martins
Browse files

audiopolicy: Add AudioSessionInfo API

 * This patch introduces a new API which allows applications to
   query the state of the audio effects system, and receive
   callbacks with the necessary information to attach effects
   to any stream.
 * In the future, this may come as part of the AudioPort system,
   but since that's an active area of development by Google, we
   will dodge it for now.
 * The policy now simply keeps a refcounted list of objects which
   hold various bits of stream metadata. Callbacks are sent on
   stream open/close to applications which might be listening
   for them.

Change-Id: I2d554d36e1378f4eb7b276010a3bfe8345c22ecd

audiopolicy: Constrain session events to music streams

 * We're really only interested in music streams right now, but
   events are being generated for all streams (system sounds, etc).
 * Constrain for now, in the future we will filter based on client
   registrations.

Change-Id: Ic445052028c454eed146addebcdb28c4b26c4f20

Author: Zhao Wei Liew <zhaoweiliew@gmail.com>
audiopolicy: Use audio_session_t consistently for AudioSessionInfo

In N, the usage of audio_session_t was made more consistent in the
commit d848eb48.

Do the same for the AudioSessionInfo API.

Change-Id: I8732225ec6788777e7be9ed42f2ca4002af47c3b

[mikeioannina]: Update for Oreo
[bgcngm]: Update for Pie

Change-Id: I2d554d36e1378f4eb7b276010a3bfe8345c22ecd
parent fa818d9a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
../../media/libaudioclient/include/media/AudioSession.h
 No newline at end of file
+38 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ Mutex AudioSystem::gLockAPS;
sp<IAudioFlinger> AudioSystem::gAudioFlinger;
sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
audio_session_callback AudioSystem::gAudioSessionCallback = NULL;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
record_config_callback AudioSystem::gRecordConfigCallback = NULL;

@@ -734,6 +735,17 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
    gRecordConfigCallback = cb;
}

/*static*/ status_t AudioSystem::setAudioSessionCallback(audio_session_callback cb)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;

    Mutex::Autolock _l(gLock);
    gAudioSessionCallback = cb;

    return NO_ERROR;
}

// client singleton for AudioPolicyService binder interface
// protected by gLockAPS
sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
@@ -1383,6 +1395,32 @@ void AudioSystem::AudioPolicyServiceClient::onRecordingConfigurationUpdate(
    }
}

// ---------------------------------------------------------------------------

status_t AudioSystem::listAudioSessions(audio_stream_type_t stream,
                                        Vector< sp<AudioSessionInfo>> &sessions)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;
    return aps->listAudioSessions(stream, sessions);
}

void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate(
        sp<AudioSessionInfo>& info, bool added)
{
    ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)",
            info->mStream, info->mSessionId, added);
    audio_session_callback cb = NULL;
    {
        Mutex::Autolock _l(AudioSystem::gLock);
        cb = gAudioSessionCallback;
    }

    if (cb != NULL) {
        cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, info, added);
    }
}

void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
{
    {
+42 −1
Original line number Diff line number Diff line
@@ -82,7 +82,8 @@ enum {
    GET_MASTER_MONO,
    GET_STREAM_VOLUME_DB,
    GET_SURROUND_FORMATS,
    SET_SURROUND_FORMAT_ENABLED
    SET_SURROUND_FORMAT_ENABLED,
    LIST_AUDIO_SESSIONS
};

#define MAX_ITEMS_PER_LIST 1024
@@ -879,6 +880,29 @@ public:
        }
        return reply.readInt32();
    }

    virtual status_t listAudioSessions(audio_stream_type_t streams,
                                       Vector< sp<AudioSessionInfo>> &sessions)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(streams);
        status_t status = remote()->transact(LIST_AUDIO_SESSIONS, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }

        status = reply.readInt32();
        if (status == NO_ERROR) {
            size_t size = (size_t)reply.readUint32();
            for (size_t i = 0; i < size && reply.dataAvail() > 0; i++) {
                sp<AudioSessionInfo> info = new AudioSessionInfo();
                info->readFromParcel(reply);
                sessions.push_back(info);
            }
        }
        return status;
    }
};

IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1436,6 +1460,23 @@ status_t BnAudioPolicyService::onTransact(
            return NO_ERROR;
        } break;

        case LIST_AUDIO_SESSIONS: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t streams = (audio_stream_type_t)data.readInt32();

            Vector< sp<AudioSessionInfo>> sessions;
            status_t status = listAudioSessions(streams, sessions);

            reply->writeInt32(status);
            if (status == NO_ERROR) {
                reply->writeUint32(static_cast<uint32_t>(sessions.size()));
                for (size_t i = 0; i < sessions.size(); i++) {
                    sessions[i]->writeToParcel(reply);
                }
            }
            return NO_ERROR;
        }

        case ACQUIRE_SOUNDTRIGGER_SESSION: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>(
+29 −1
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@ enum {
    PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION,
    PATCH_LIST_UPDATE,
    MIX_STATE_UPDATE,
    RECORDING_CONFIGURATION_UPDATE
    RECORDING_CONFIGURATION_UPDATE,
    OUTPUT_SESSION_EFFECTS_UPDATE
};

// ----------------------------------------------------------------------
@@ -104,6 +105,19 @@ public:
        data.writeInt32(patchHandle);
        remote()->transact(RECORDING_CONFIGURATION_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
    }

    void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
        data.writeInt32(info->mStream);
        data.writeInt32(info->mSessionId);
        data.writeInt32(info->mFlags);
        data.writeInt32(info->mChannelMask);
        data.writeInt32(info->mUid);
        data.writeInt32(added ? 1 : 0);
        remote()->transact(OUTPUT_SESSION_EFFECTS_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
    }
};

IMPLEMENT_META_INTERFACE(AudioPolicyServiceClient, "android.media.IAudioPolicyServiceClient");
@@ -145,6 +159,20 @@ status_t BnAudioPolicyServiceClient::onTransact(
                    patchHandle);
            return NO_ERROR;
        } break;
    case OUTPUT_SESSION_EFFECTS_UPDATE: {
            CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
            audio_stream_type_t stream = static_cast<audio_stream_type_t>(data.readInt32());
            audio_session_t sessionId = static_cast<audio_session_t>(data.readInt32());
            audio_output_flags_t flags = static_cast<audio_output_flags_t>(data.readInt32());
            audio_channel_mask_t channelMask = static_cast<audio_channel_mask_t>(data.readInt32());
            uid_t uid = static_cast<uid_t>(data.readInt32());
            bool added = data.readInt32() > 0;

            sp<AudioSessionInfo> info = new AudioSessionInfo(
                    sessionId, stream, flags, channelMask, uid);
            onOutputSessionEffectsUpdate(info, added);
            return NO_ERROR;
        } break;
    default:
        return BBinder::onTransact(code, data, reply, flags);
    }
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/Vector.h>
#include <media/AudioSession.h>

namespace android {

@@ -44,6 +45,7 @@ namespace android {
//   AudioSystem's implementation of the AudioPolicyClient interface
// keep in sync with AudioSystem.java
#define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0
#define AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE 10

#define MIX_STATE_DISABLED (-1)
#define MIX_STATE_IDLE 0
Loading