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

Commit ddf87eff authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AudioFlinger: enforce OP_RECORD_AUDIO during recording

  Fix issue where RecordTrack silencing didn't silence the
full buffer: the memset to 0 was using the RecordThread frame
size, not the RecordTrack frame size.
  OP_RECORD_AUDIO was only enforced at the start of a recording
which would fail if not granted. This patch silences the recording
(i.e. silence is recorded instead) when it is lost, and undoes that
when granted again. This requires:
- propagating the package name of the client to the RecordTrack class
- registering an appOp callback in RecordTrack (through a new
  OpRecordAudioMonitor class) to (un)silence the recording
- update the isSilenced() method to take into account the appOp.

Bug: 138968594
Test: run app that records audio, then "adb shell appops __pack_name__ 27 2"
     and verify recording is silent after that.

Change-Id: Ib33f5b592185a67204997213bab1ac2594d90d37
parent 28355761
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1933,7 +1933,8 @@ sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& inpu
                                                  &output.notificationFrameCount,
                                                  callingPid, clientUid, &output.flags,
                                                  input.clientInfo.clientTid,
                                                  &lStatus, portId);
                                                  &lStatus, portId,
                                                  input.opPackageName);
        LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));

        // lStatus == BAD_TYPE means FAST flag was rejected: request a new input from
+40 −1
Original line number Diff line number Diff line
@@ -19,6 +19,39 @@
    #error This header file should only be included from AudioFlinger.h
#endif

// Checks and monitors OP_RECORD_AUDIO
class OpRecordAudioMonitor : public RefBase {
public:
    ~OpRecordAudioMonitor() override;
    bool hasOpRecordAudio() const;

    static sp<OpRecordAudioMonitor> createIfNeeded(uid_t uid, const String16& opPackageName);

private:
    OpRecordAudioMonitor(uid_t uid, const String16& opPackageName);
    void onFirstRef() override;

    AppOpsManager mAppOpsManager;

    class RecordAudioOpCallback : public BnAppOpsCallback {
    public:
        explicit RecordAudioOpCallback(const wp<OpRecordAudioMonitor>& monitor);
        void opChanged(int32_t op, const String16& packageName) override;

    private:
        const wp<OpRecordAudioMonitor> mMonitor;
    };

    sp<RecordAudioOpCallback> mOpCallback;
    // called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
    // and in onFirstRef()
    void checkRecordAudio();

    std::atomic_bool mHasOpRecordAudio;
    const uid_t mUid;
    const String16 mPackage;
};

// record track
class RecordTrack : public TrackBase {
public:
@@ -36,6 +69,7 @@ public:
                                uid_t uid,
                                audio_input_flags_t flags,
                                track_type type,
                                const String16& opPackageName,
                                audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
    virtual             ~RecordTrack();
    virtual status_t    initCheck() const;
@@ -68,7 +102,7 @@ public:
                                { return (mFlags & AUDIO_INPUT_FLAG_DIRECT) != 0; }

            void        setSilenced(bool silenced) { if (!isPatchTrack()) mSilenced = silenced; }
            bool        isSilenced() const { return mSilenced; }
            bool        isSilenced() const;

            status_t    getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);

@@ -111,6 +145,11 @@ private:
            audio_input_flags_t                mFlags;

            bool                               mSilenced;

            // used to enforce OP_RECORD_AUDIO
            uid_t                              mUid;
            String16                           mOpPackageName;
            sp<OpRecordAudioMonitor>           mOpRecordAudioMonitor;
};

// playback track, used by PatchPanel
+4 −3
Original line number Diff line number Diff line
@@ -7291,7 +7291,7 @@ reacquire_wakelock:
                        // Sanitize before releasing if the track has no access to the source data
                        // An idle UID receives silence from non virtual devices until active
                        if (activeTrack->isSilenced()) {
                            memset(activeTrack->mSink.raw, 0, framesOut * mFrameSize);
                            memset(activeTrack->mSink.raw, 0, framesOut * activeTrack->frameSize());
                        }
                        activeTrack->releaseBuffer(&activeTrack->mSink);
                    }
@@ -7452,7 +7452,8 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe
        audio_input_flags_t *flags,
        pid_t tid,
        status_t *status,
        audio_port_handle_t portId)
        audio_port_handle_t portId,
        const String16& opPackageName)
{
    size_t frameCount = *pFrameCount;
    size_t notificationFrameCount = *pNotificationFrameCount;
@@ -7586,7 +7587,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe
        track = new RecordTrack(this, client, attr, sampleRate,
                      format, channelMask, frameCount,
                      nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, creatorPid, uid,
                      *flags, TrackBase::TYPE_DEFAULT, portId);
                      *flags, TrackBase::TYPE_DEFAULT, opPackageName, portId);

        lStatus = track->initCheck();
        if (lStatus != NO_ERROR) {
+2 −1
Original line number Diff line number Diff line
@@ -1553,7 +1553,8 @@ public:
                    audio_input_flags_t *flags,
                    pid_t tid,
                    status_t *status /*non-NULL*/,
                    audio_port_handle_t portId);
                    audio_port_handle_t portId,
                    const String16& opPackageName);

            status_t    start(RecordTrack* recordTrack,
                              AudioSystem::sync_event_t event,
+2 −0
Original line number Diff line number Diff line
@@ -215,6 +215,8 @@ protected:

    uint32_t channelCount() const { return mChannelCount; }

    size_t frameSize() const { return mFrameSize; }

    audio_channel_mask_t channelMask() const { return mChannelMask; }

    virtual uint32_t sampleRate() const { return mSampleRate; }
Loading