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

Commit dfd9c5cc authored by Eric Laurent's avatar Eric Laurent
Browse files

audioflinger: add support for GMAP mode

Add support for insertion of special tag in playback
track metadata to indicate request for bidirectional mode to the
BT stack for GMAP mode.
If an apk has been recording audio in the past and plays for game
usage, bidirectional mode is assumed.
This is a short term work around until a proper API is introduced
for explicit indication of bidirectional request by the app.

Bug: 366456949
Test: make
Flag: com.android.media.audioserver.enable_gmap_mode
Change-Id: Ib490660dc9af6c808ba91b154ae4714a83f28bc6
parent 2da34c08
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@
#define ALOGVV(a...) do { } while(0)
#endif

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

namespace android {

using namespace std::string_view_literals;
@@ -627,6 +629,11 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
        }
    }
    if (ret != NO_ERROR) {
        if (audioserver_flags::enable_gmap_mode()
                && direction == MmapStreamInterface::DIRECTION_INPUT) {
            audio_utils::lock_guard _l(mutex());
            setHasAlreadyCaptured_l(adjAttributionSource.uid);
        }
        return ret;
    }

@@ -2541,6 +2548,9 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input,
            audio_utils::lock_guard _l2(thread->mutex());
            thread->addEffectChain_l(chain);
        }
        if (audioserver_flags::enable_gmap_mode()) {
            setHasAlreadyCaptured_l(adjAttributionSource.uid);
        }
        break;
    }
    // End of retry loop.
@@ -2577,6 +2587,26 @@ Exit:

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

void AudioFlinger::setHasAlreadyCaptured_l(uid_t uid) {
    {
        const std::lock_guard _l(mCapturingClientsMutex);
        if (mCapturingClients.count(uid)) return;
        mCapturingClients.emplace(uid);
    }
    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        IAfPlaybackThread* const playbackThread = mPlaybackThreads.valueAt(i).get();
        playbackThread->checkUpdateTrackMetadataForUid(uid);
    }
    for (size_t i = 0; i < mMmapThreads.size(); i++) {
        IAfMmapThread* const mmapThread = mMmapThreads.valueAt(i).get();
        if (mmapThread->isOutput()) {
            IAfMmapPlaybackThread* const mmapPlaybackThread =
                    mmapThread->asIAfMmapPlaybackThread().get();
            mmapPlaybackThread->checkUpdateTrackMetadataForUid(uid);
        }
    }
}

status_t AudioFlinger::getAudioPolicyConfig(media::AudioPolicyConfig *config)
{
    if (config == nullptr) {
+13 −0
Original line number Diff line number Diff line
@@ -417,8 +417,15 @@ private:

    bool isHardeningOverrideEnabled() const final;

    bool hasAlreadyCaptured(uid_t uid) const final {
        const std::lock_guard _l(mCapturingClientsMutex);
        return mCapturingClients.contains(uid);
    }

    // ---- end of IAfThreadCallback interface

    void setHasAlreadyCaptured_l(uid_t uid) REQUIRES(mutex());

    /* List available audio ports and their attributes */
    status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const
            EXCLUDES_AudioFlinger_Mutex;
@@ -788,6 +795,12 @@ private:
    const int64_t mStartTime = audio_utils_get_real_time_ns();
    // Late-inited from main()
    std::atomic<int64_t> mStartupFinishedTime {};

    // List of client UIDs having already captured audio in the past.
    // This is used to control GMAP bidirectional mode track metadata tag
    // generation.
    std::set<uid_t> mCapturingClients GUARDED_BY(mCapturingClientsMutex);
    mutable std::mutex  mCapturingClientsMutex; // only for mCapturingClients
};

// ----------------------------------------------------------------------------
+4 −0
Original line number Diff line number Diff line
@@ -130,6 +130,8 @@ public:
            getPermissionProvider() = 0;

    virtual bool isHardeningOverrideEnabled() const = 0;

    virtual bool hasAlreadyCaptured(uid_t uid) const = 0;
};

class IAfThreadBase : public virtual RefBase {
@@ -565,6 +567,7 @@ public:

    virtual status_t setPortsVolume(const std::vector<audio_port_handle_t> &portIds, float volume,
                                    bool muted) EXCLUDES_ThreadBase_Mutex = 0;
    virtual void checkUpdateTrackMetadataForUid(uid_t uid) EXCLUDES_ThreadBase_Mutex = 0;
};

class IAfDirectOutputThread : public virtual IAfPlaybackThread {
@@ -710,6 +713,7 @@ public:

    virtual status_t setPortsVolume(const std::vector<audio_port_handle_t>& portIds, float volume,
                                    bool muted) EXCLUDES_ThreadBase_Mutex = 0;
    virtual void checkUpdateTrackMetadataForUid(uid_t uid) EXCLUDES_ThreadBase_Mutex = 0;
};

class IAfMmapCaptureThread : public virtual IAfMmapThread {
+33 −3
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@
#include <audio_utils/MelProcessor.h>
#include <audio_utils/Metadata.h>
#include <audio_utils/Trace.h>
#include <com_android_media_audioserver.h>
#ifdef DEBUG_CPU_USAGE
#include <audio_utils/Statistics.h>
#include <cpustats/ThreadCpuUsage.h>
@@ -2897,6 +2896,15 @@ void PlaybackThread::setVolumeForOutput_l(float left, float right) const
    mOutput->stream->setVolume(left, right);
}

void PlaybackThread::checkUpdateTrackMetadataForUid(uid_t uid) {
    audio_utils::lock_guard _l(mutex());
    for (const sp<IAfTrack>& track : mActiveTracks) {
        if (track->uid() == uid) {
            track->setMetadataHasChanged();
        }
    }
}

// addTrack_l() must be called with ThreadBase::mutex() held
status_t PlaybackThread::addTrack_l(const sp<IAfTrack>& track)
{
@@ -11365,6 +11373,15 @@ status_t MmapPlaybackThread::setPortsVolume(
    return NO_ERROR;
}

void MmapPlaybackThread::checkUpdateTrackMetadataForUid(uid_t uid) {
    audio_utils::lock_guard _l(mutex());
    for (const sp<IAfMmapTrack>& track : mActiveTracks) {
        if (track->uid() == uid) {
            track->setMetadataHasChanged();
        }
    }
}

void MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
    audio_utils::lock_guard _l(mutex());
@@ -11506,8 +11523,21 @@ ThreadBase::MetadataUpdate MmapPlaybackThread::updateMetadata_l()
                .content_type = track->attributes().content_type,
                .gain = mHalVolFloat, // TODO: propagate from aaudio pre-mix volume
        };
        trackMetadata.channel_mask = track->channelMask(),
        strncpy(trackMetadata.tags, track->attributes().tags, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
        trackMetadata.channel_mask = track->channelMask();
        std::string tagStr(track->attributes().tags);
        if (audioserver_flags::enable_gmap_mode() && track->attributes().usage == AUDIO_USAGE_GAME
                && afThreadCallback()->hasAlreadyCaptured(track->uid())
                && (tagStr.size() + strlen(AUDIO_ATTRIBUTES_TAG_GMAP_BIDIRECTIONAL)
                    + (tagStr.size() ? 1 : 0))
                    < AUDIO_ATTRIBUTES_TAGS_MAX_SIZE) {

            if (tagStr.size() != 0) {
                tagStr.append(1, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
            }
            tagStr.append(AUDIO_ATTRIBUTES_TAG_GMAP_BIDIRECTIONAL);
        }
        strncpy(trackMetadata.tags, tagStr.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
        trackMetadata.tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1] = '\0';
        metadata.tracks.push_back(trackMetadata);
    }
    mOutput->stream->updateSourceMetadata(metadata);
+4 −0
Original line number Diff line number Diff line
@@ -1241,6 +1241,8 @@ public:

    std::string getLocalLogHeader() const override;

    void checkUpdateTrackMetadataForUid(uid_t uid) final EXCLUDES_ThreadBase_Mutex;

protected:
    // updated by readOutputParameters_l()
    size_t                          mNormalFrameCount;  // normal mixer and effects
@@ -2451,6 +2453,8 @@ public:
    void stopMelComputation_l() final
            REQUIRES(audio_utils::AudioFlinger_Mutex);

    void checkUpdateTrackMetadataForUid(uid_t uid) final EXCLUDES_ThreadBase_Mutex;

protected:
    void dumpInternals_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
    float streamVolume_l() const REQUIRES(mutex()) {
Loading