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

Commit 2996f677 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

AudioPolicy/AudioFlinger: Track AudioRecords via Record IDs

The client must provide a unique Record ID (RIID) when creating
an AudioRecord. This RIID is passed down to AudioInputDescriptor
in AudioPolicyManager which sends configuration updates
via IAudioPolicyServiceClient callback.

By supplying RIID, the Audio Service can coalesce start / stop
events coming from clients (apps) with recording configuration
update events.

For AAudio MMap clients everything is handled at the server
side because they correspond directly to audioserver objects.

Bug: 123312504
Test: android.media.cts.AudioRecordingConfigurationTest
      AudioRecordTest#testAudioRecordInfoCallback
      MediaRecorderTest#testAudioRecordInfoCallback
      manual testing using Oboe and Solo test apps

Change-Id: I3d32241752d9a747736606dc4cb1e068e6b7aa3b
parent 3208826f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ cc_library_shared {
        "IEffectClient.cpp",
        "ToneGenerator.cpp",
        "PlayerBase.cpp",
        "RecordingActivityTracker.cpp",
        "TrackPlayerBase.cpp",
    ],
    shared_libs: [
+11 −4
Original line number Diff line number Diff line
@@ -22,7 +22,11 @@
#include <android-base/macros.h>
#include <sys/resource.h>

#include <audiomanager/AudioManager.h>
#include <audiomanager/IAudioManager.h>
#include <binder/Binder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <media/AudioRecord.h>
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
@@ -219,6 +223,8 @@ status_t AudioRecord::set(
          inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
          sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid);

    mTracker.reset(new RecordingActivityTracker());

    mSelectedDeviceId = selectedDeviceId;
    mSelectedMicDirection = selectedMicDirection;
    mSelectedMicFieldDimension = microphoneFieldDimension;
@@ -396,6 +402,7 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t tri
    // This is legacy behavior.  This is not done in stop() to avoid a race condition
    // where the last marker event is issued twice.
    mMarkerReached = false;
    // mActive is checked by restoreRecord_l
    mActive = true;

    status_t status = NO_ERROR;
@@ -416,7 +423,9 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t tri
    if (status != NO_ERROR) {
        mActive = false;
        ALOGE("%s(%d): status %d", __func__, mPortId, status);
        mMediaMetrics.markError(status, __FUNCTION__);
    } else {
        mTracker->recordingStarted();
        sp<AudioRecordThread> t = mAudioRecordThread;
        if (t != 0) {
            t->resume();
@@ -429,10 +438,6 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t tri
        // we've successfully started, log that time
        mMediaMetrics.logStart(systemTime());
    }

    if (status != NO_ERROR) {
        mMediaMetrics.markError(status, __FUNCTION__);
    }
    return status;
}

@@ -447,6 +452,7 @@ void AudioRecord::stop()
    mActive = false;
    mProxy->interrupt();
    mAudioRecord->stop();
    mTracker->recordingStopped();

    // Note: legacy handling - stop does not clear record marker and
    // periodic update position; we update those on start().
@@ -711,6 +717,7 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
        }
    }
    input.opPackageName = opPackageName;
    input.riid = mTracker->getRiid();

    input.flags = mFlags;
    // The notification frame count is the period between callbacks, as suggested by the client
+3 −1
Original line number Diff line number Diff line
@@ -428,6 +428,7 @@ uint32_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle)

audio_unique_id_t AudioSystem::newAudioUniqueId(audio_unique_id_use_t use)
{
    // Must not use AF as IDs will re-roll on audioserver restart, b/130369529.
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
    return af->newAudioUniqueId(use);
@@ -924,6 +925,7 @@ void AudioSystem::releaseOutput(audio_port_handle_t portId)

status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
                                audio_io_handle_t *input,
                                audio_unique_id_t riid,
                                audio_session_t session,
                                pid_t pid,
                                uid_t uid,
@@ -936,7 +938,7 @@ status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return NO_INIT;
    return aps->getInputForAttr(
            attr, input, session, pid, uid, opPackageName,
            attr, input, riid, session, pid, uid, opPackageName,
            config, flags, selectedDeviceId, portId);
}

+4 −1
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ public:

    virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
                                     audio_unique_id_t riid,
                                     audio_session_t session,
                                     pid_t pid,
                                     uid_t uid,
@@ -334,6 +335,7 @@ public:
        }
        data.write(attr, sizeof(audio_attributes_t));
        data.writeInt32(*input);
        data.writeInt32(riid);
        data.writeInt32(session);
        data.writeInt32(pid);
        data.writeInt32(uid);
@@ -1511,6 +1513,7 @@ status_t BnAudioPolicyService::onTransact(
            data.read(&attr, sizeof(audio_attributes_t));
            sanetizeAudioAttributes(&attr);
            audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
            audio_unique_id_t riid = (audio_unique_id_t)data.readInt32();
            audio_session_t session = (audio_session_t)data.readInt32();
            pid_t pid = (pid_t)data.readInt32();
            uid_t uid = (uid_t)data.readInt32();
@@ -1521,7 +1524,7 @@ status_t BnAudioPolicyService::onTransact(
            audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
            audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
            audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
            status_t status = getInputForAttr(&attr, &input, session, pid, uid,
            status_t status = getInputForAttr(&attr, &input, riid, session, pid, uid,
                                              opPackageName, &config,
                                              flags, &selectedDeviceId, &portId);
            reply->writeInt32(status);
+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ inline void writeAudioConfigBaseToParcel(Parcel& data, const audio_config_base_t
}

inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_info_t *clientInfo) {
    clientInfo->riid = (audio_unique_id_t) data.readInt32();
    clientInfo->uid = (uid_t) data.readUint32();
    clientInfo->session = (audio_session_t) data.readInt32();
    clientInfo->source = (audio_source_t) data.readInt32();
@@ -58,6 +59,7 @@ inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_inf
}

inline void writeRecordClientInfoToParcel(Parcel& data, const record_client_info_t *clientInfo) {
    data.writeInt32((int32_t) clientInfo->riid);
    data.writeUint32((uint32_t) clientInfo->uid);
    data.writeInt32((int32_t) clientInfo->session);
    data.writeInt32((int32_t) clientInfo->source);
Loading