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

Commit 90fd4455 authored by Atneya Nair's avatar Atneya Nair
Browse files

Reapply "Add partial audio playback hardening"

This reverts commit 34982d91.

Change-Id: I894663c4a17febfcb7c8334a4dcef402b682f1a7
parent 72974519
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <audio_utils/mutex.h>
#include <audio_utils/LinearMap.h>
#include <binder/AppOpsManager.h>
#include <media/AppOpsSession.h>
#include <utils/RWLock.h>

namespace android {
@@ -297,8 +298,7 @@ protected:
    }

    bool isPlaybackRestrictedControl() const final {
        return false;
        // return mOpAudioControlSoftMonitor ? !mOpAudioControlSoftMonitor->hasOp() : false;
        return mOpControlSession ? !mHasOpControl.load(std::memory_order_acquire) : false;
    }

    bool isPlaybackRestricted() const final {
@@ -353,6 +353,12 @@ protected:

    sp<OpPlayAudioMonitor>  mOpPlayAudioMonitor;

    // logically const
    std::optional<media::permission::AppOpsSession<media::permission::DefaultAppOpsFacade>>
            mOpControlSession;

    std::atomic<bool> mHasOpControl {true};

    bool                mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
    // scale to play haptic data
    os::HapticScale mHapticScale = os::HapticScale::mute();
+43 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <audio_utils/StringUtils.h>
#include <audio_utils/minifloat.h>
#include <com_android_media_audio.h>
#include <media/AppOpsSession.h>
#include <media/AudioValidator.h>
#include <media/IPermissionProvider.h>
#include <media/RecordBufferConverter.h>
@@ -72,6 +73,7 @@
namespace android {

using ::android::aidl_utils::binderStatusFromStatusT;
using ::com::android::media::audio::hardening_impl;
using binder::Status;
using com::android::media::audio::audioserver_permissions;
using com::android::media::permission::PermissionEnum::CAPTURE_AUDIO_HOTWORD;
@@ -939,6 +941,26 @@ Track::Track(
        return;
    }

    using media::permission::ValidatedAttributionSourceState;
    using media::permission::Ops;

    if (hardening_impl()) {
        // Don't bother for non-output tracks and server uids
        if (!media::permission::skipOpsForUid(attributionSource.uid) && type != TYPE_PATCH) {
            mOpControlSession.emplace(
                ValidatedAttributionSourceState::createFromTrustedSource(attributionSource),
                Ops { .attributedOp = AppOpsManager::OP_CONTROL_AUDIO_PARTIAL },
                [this]
                (bool isPermitted) {
                    mHasOpControl.store(isPermitted, std::memory_order_release);
                    if (isOffloaded()) {
                        signal();
                    }
                }
            );
        }
    }

    if (sharedBuffer == 0) {
        mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
                mFrameSize, !isExternalTrack(), sampleRate);
@@ -1506,6 +1528,13 @@ status_t Track::start(AudioSystem::sync_event_t event __unused,
        status = BAD_VALUE;
    }
    if (status == NO_ERROR) {
        // start OP_AUDIO_CONTROL session for track
        // TODO(b/385417236) once mute logic is centralized, the delivery request session should be
        // tied to sonifying playback instead of track start->pause
        if (mOpControlSession) {
            mHasOpControl.store(mOpControlSession->beginDeliveryRequest(),
                                std::memory_order_release);
        }
        // send format to AudioManager for playback activity monitoring
        const sp<IAudioManager> audioManager =
                thread->afThreadCallback()->getOrCreateAudioManager();
@@ -1567,6 +1596,15 @@ void Track::stop()
        }
        forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->stop(); });
    }
    // TODO(b/385417236)
    // Due to the complexity of state management for offload we do not call endDeliveryRequest().
    // For offload tracks, sonification may continue significantly after the STOP
    // phase begins. Leave the session on-going until the track is eventually
    // destroyed. We continue to allow appop callbacks during STOPPING and STOPPED state.
    // This is suboptimal but harmless.
    if (mOpControlSession && !isOffloaded()) {
        mOpControlSession->endDeliveryRequest();
    }
}

void Track::pause()
@@ -1611,6 +1649,11 @@ void Track::pause()
        // Pausing the TeePatch to avoid a glitch on underrun, at the cost of buffered audio loss.
        forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->pause(); });
    }
    // When stopping a paused track, there will be two endDeliveryRequests. This is tolerated by
    // the implementation.
    if (mOpControlSession) {
        mOpControlSession->endDeliveryRequest();
    }
}

void Track::flush()