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

Commit ea271c1b authored by Atneya Nair's avatar Atneya Nair
Browse files

[audio] Add logging/metrics for playback hardening

Notify AudioService when a track encounters playback hardening for
metrics/app debugging/logging purposes.

The enforcement may be exempted for certain reasons (such as usage), but
ensure that we log anyways for metrics/visibility so we can chase down
exemptions.

We only dispatch this notification once per track instance for more
useful metrics and to avoid log spam.

Test: atest android.virtualdevice.cts.audio.VirtualAudioTest manual log
verification
Test: oboetester silenced audio manual log verification
Bug: 376481063
Flag: com.android.media.audio.hardening_impl

Change-Id: I9c76f7e5691a518461a8d002f08cd0e7c88ebd5c
parent d0abe031
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -382,6 +382,14 @@ public:
    virtual audio_output_flags_t getOutputFlags() const = 0;
    virtual float getSpeed() const = 0;

    /**
     * Inform AudioService of any potential playback restriction due to fg state.
     * Should be called when evaluating playback restrictions due to fg state
     * (see {@link isPlaybackRestrictedControl()}). This function
     * internally checks the OP state and dispatches to AudioService for metrics
     */
    virtual void maybeLogPlaybackHardening(media::IAudioManagerNative& am) const = 0;

    /**
     * Updates the mute state and notifies the audio service. Call this only when holding player
     * thread lock.
+3 −0
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ public:
    bool isSpatialized() const final { return mIsSpatialized; }
    bool isBitPerfect() const final { return mIsBitPerfect; }

    void maybeLogPlaybackHardening(media::IAudioManagerNative& am) const final;
    /**
     * Updates the mute state and notifies the audio service. Call this only when holding player
     * thread lock.
@@ -367,6 +368,8 @@ protected:
    bool mIsExemptedFromOpControl = false;
    std::atomic<bool> mHasOpControlPartial {true};

    mutable std::atomic<bool> mPlaybackHardeningLogged {false};

    bool                mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
    // scale to play haptic data
    os::HapticScale mHapticScale = os::HapticScale::mute();
+7 −0
Original line number Diff line number Diff line
@@ -5865,6 +5865,8 @@ PlaybackThread::mixer_state MixerThread::prepareTracks_l(
                        volume = masterVolume * track->getPortVolume();
                    }
                }
                track->maybeLogPlaybackHardening(
                        *mAfThreadCallback->getOrCreateAudioManager()->getNativeInterface());
                handleVoipVolume_l(&volume);

                // cache the combined master volume and stream type volume for fast mixer; this
@@ -6062,6 +6064,8 @@ PlaybackThread::mixer_state MixerThread::prepareTracks_l(
                }
            }
            handleVoipVolume_l(&v);
            track->maybeLogPlaybackHardening(
                    *mAfThreadCallback->getOrCreateAudioManager()->getNativeInterface());

            if (track->isPausing()) {
                vl = vr = 0;
@@ -6891,6 +6895,9 @@ void DirectOutputThread::processVolume_l(IAfTrack* track, bool lastTrack)
                               track->getPortMute(),
                               track->isPlaybackRestrictedControl()});
    }
    track->maybeLogPlaybackHardening(
            *mAfThreadCallback->getOrCreateAudioManager()->getNativeInterface());


    if (lastTrack) {
        track->setFinalVolume(left, right);
+14 −0
Original line number Diff line number Diff line
@@ -1904,6 +1904,20 @@ void Track::setTeePatchesToUpdate_l(TeePatches teePatchesToUpdate) {
    mTeePatchesToUpdate = std::move(teePatchesToUpdate);
}

void Track::maybeLogPlaybackHardening(media::IAudioManagerNative& am) const {
    using media::IAudioManagerNative::HardeningType::PARTIAL;
    // The op state deviates from if the track is actually muted if the playback was exempted for
    // some compat reason.
    // The state could have technically TOCTOU, but this is for metrics and that is very unlikely
    if (!hasOpControlPartial()) {
        if (!mPlaybackHardeningLogged.exchange(true, std::memory_order_acq_rel)) {
            am.playbackHardeningEvent(uid(), PARTIAL,
                                             /* bypassed= */
                                             !isPlaybackRestrictedControl());
        }
    }

}
// must be called with player thread lock held
void Track::processMuteEvent_l(const sp<
    IAudioManager>& audioManager, mute_state_t muteState)