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

Commit 90574aa0 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[audio] Offload thread signal to prevent deadlock" into main

parents 3639495c 0b53f60b
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <audiomanager/IAudioManager.h>
#include <binder/IMemory.h>
#include <media/AppOpsSession.h>
#include <mediautils/SingleThreadExecutor.h>
#include <datapath/VolumePortInterface.h>
#include <fastpath/FastMixerDumpState.h>
#include <media/AudioSystem.h>
@@ -268,9 +269,10 @@ class AfPlaybackCommon : public virtual VolumePortInterface {
    using AppOpsSession = media::permission::AppOpsSession<media::permission::DefaultAppOpsFacade>;

  public:
    AfPlaybackCommon(IAfTrackBase& self, IAfThreadCallback& thread, float volume, bool muted,
    AfPlaybackCommon(IAfTrackBase& self, IAfThreadBase& thread, float volume, bool muted,
                     const audio_attributes_t& attr,
                     const AttributionSourceState& attributionSource,
                     bool isOffloadOrMmap,
                     bool shouldPlaybackHarden = true);

    /**
@@ -312,11 +314,9 @@ class AfPlaybackCommon : public virtual VolumePortInterface {
    void endPlaybackDelivery();

  private:
    // non-const for signal
    IAfTrackBase& mSelf;
    // TODO: replace PersistableBundle with own struct
    // access these two variables only when holding player thread lock.
    std::unique_ptr<os::PersistableBundle> mMuteEventExtras;
    const IAfTrackBase& mSelf;

    std::optional<mediautils::SingleThreadExecutor> mExecutor;
    // TODO: atomic necessary if underneath thread lock?
    std::atomic<mute_state_t> mMuteState;
    std::atomic<bool> mMutedFromPort;
@@ -328,6 +328,7 @@ class AfPlaybackCommon : public virtual VolumePortInterface {
    std::atomic<bool> mHasOpControlPartial {true};
    mutable std::atomic<bool> mPlaybackHardeningLogged {false};
    // the ref behind the optional is const
    // this member is last in decl order to ensure it is destroyed first
    std::optional<AppOpsSession> mOpControlSession;
};

+29 −12
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <media/RecordBufferConverter.h>
#include <media/nbaio/Pipe.h>
#include <media/nbaio/PipeReader.h>
#include <mediautils/Runnable.h>
#include <mediautils/ServiceUtilities.h>
#include <mediautils/SharedMemoryAllocator.h>
#include <private/media/AudioTrackShared.h>
@@ -879,8 +880,8 @@ Track::Track(
            float volume,
            bool muted)
    :
    AfPlaybackCommon(*this, *thread->afThreadCallback(), volume, muted,
                     attr, attributionSource, type != TYPE_PATCH),
    AfPlaybackCommon(*this, *thread, volume, muted,
                     attr, attributionSource, thread->isOffloadOrMmap(), type != TYPE_PATCH),
    TrackBase(thread, client, attr, sampleRate, format, channelMask, frameCount,
                  // TODO: Using unsecurePointer() has some associated security pitfalls
                  //       (see declaration for details).
@@ -2322,9 +2323,9 @@ OutputTrack::OutputTrack(
            size_t frameCount,
            const AttributionSourceState& attributionSource)
    :
    AfPlaybackCommon(*this, *playbackThread->afThreadCallback(), /* volume= */ 0.0f,
    AfPlaybackCommon(*this, *playbackThread, /* volume= */ 0.0f,
                     /* muted= */ false,
                     AUDIO_ATTRIBUTES_INITIALIZER, attributionSource,
                     AUDIO_ATTRIBUTES_INITIALIZER, attributionSource, /* isOffloadOrMmap= */ false,
                     /* shouldPlaybackHarden= */ false),
    Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
              AUDIO_ATTRIBUTES_INITIALIZER ,
@@ -2634,9 +2635,10 @@ PatchTrack::PatchTrack(IAfPlaybackThread* playbackThread,
                                                     float speed,
                                                     float volume,
                                                     bool muted)
    : AfPlaybackCommon(*this, *playbackThread->afThreadCallback(), volume, muted,
    : AfPlaybackCommon(*this, *playbackThread, volume, muted,
                       AUDIO_ATTRIBUTES_INITIALIZER,
                       audioServerAttributionSource(getpid()),
                       /* isOffloadOrMmap= */ false,
                       /* shouldPlaybackHarden= */ false),
    Track(playbackThread, NULL, streamType,
              AUDIO_ATTRIBUTES_INITIALIZER,
@@ -3680,14 +3682,15 @@ static bool shouldExemptFromOpControl(audio_usage_t usage, IAfThreadCallback& cb
    }
}

AfPlaybackCommon::AfPlaybackCommon(IAfTrackBase& self, IAfThreadCallback& threadCb, float volume,
AfPlaybackCommon::AfPlaybackCommon(IAfTrackBase& self, IAfThreadBase& thread, float volume,
                                   bool muted, const audio_attributes_t& attr,
                                   const AttributionSourceState& attributionSource,
                                   bool isOffloadOrMmap,
                                   bool shouldPlaybackHarden)
    : mSelf(self),
      mMutedFromPort(muted),
      mVolume(volume),
      mIsExemptedFromOpControl(shouldExemptFromOpControl(attr.usage, threadCb)) {
      mIsExemptedFromOpControl(shouldExemptFromOpControl(attr.usage, *thread.afThreadCallback())) {
    using AppOpsManager::OP_CONTROL_AUDIO_PARTIAL;
    using media::permission::Ops;
    using media::permission::skipOpsForUid;
@@ -3696,12 +3699,26 @@ AfPlaybackCommon::AfPlaybackCommon(IAfTrackBase& self, IAfThreadCallback& thread
    if (hardening_impl()) {
        // Don't bother for trusted uids
        if (!skipOpsForUid(attributionSource.uid) && shouldPlaybackHarden) {
            if (isOffloadOrMmap) {
                mExecutor.emplace();
            }
            auto thread_wp = wp<IAfThreadBase>::fromExisting(&thread);
            mOpControlSession.emplace(
                    ValidatedAttributionSourceState::createFromTrustedSource(attributionSource),
                    Ops{.attributedOp = OP_CONTROL_AUDIO_PARTIAL}, [this](bool isPermitted) {
                    Ops{.attributedOp = OP_CONTROL_AUDIO_PARTIAL},
                    [this, isOffloadOrMmap, thread_wp](bool isPermitted) {
                        mHasOpControlPartial.store(isPermitted, std::memory_order_release);
                        mSelf.signal();
                    });
                        if (isOffloadOrMmap) {
                            mExecutor->enqueue(mediautils::Runnable{[thread_wp]() {
                                auto thread = thread_wp.promote();
                                if (thread != nullptr) {
                                    audio_utils::lock_guard l {thread->mutex()};
                                    thread->broadcast_l();
                                }
                            }});
                        }
                    }
            );
        }
    }
}
@@ -3799,8 +3816,8 @@ MmapTrack::MmapTrack(IAfThreadBase* thread,
        audio_port_handle_t portId,
        float volume,
        bool muted)
    :   AfPlaybackCommon(*this, *thread->afThreadCallback(),
                         volume, muted, attr, attributionSource),
    :   AfPlaybackCommon(*this, *thread,
                         volume, muted, attr, attributionSource, /* isOffloadOrMmap */ true),
        TrackBase(thread, NULL, attr, sampleRate, format,
                  channelMask, (size_t)0 /* frameCount */,
                  nullptr /* buffer */, (size_t)0 /* bufferSize */,