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

Commit 5ee38243 authored by jiabin's avatar jiabin Committed by Jiabin Huang
Browse files

Cache MMAP client silenced state.

When starting MMAP input stream, APM will check if the client is allowed
to capture at that moment or not and call setRecordSilenced if the
client is not allowed. However, the client is not active when starting
the MMAP input stream. In that case, the client silenced state will be
lost and the client will be able to capture even though it is not
allowed. In this CL, when setRecordSilenced is called, it will cache
the client silenced state so that it can apply when the client is
active.

Test: atest AAudioTests
Test: repo steps from the bug
Bug: 235850634
Change-Id: I49b5a0f08d1747053f868db6e88c0f677256fc3c
Merged-In: I49b5a0f08d1747053f868db6e88c0f677256fc3c
(cherry picked from commit 0960903b)
parent 9d33304e
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -8646,6 +8646,12 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
    if (isOutput()) {
        ret = AudioSystem::startOutput(portId);
    } else {
        {
            // Add the track record before starting input so that the silent status for the
            // client can be cached.
            Mutex::Autolock _l(mLock);
            setClientSilencedStateIfNotExist_l(client.clientUid, false /*silenced*/);
        }
        ret = AudioSystem::startInput(portId);
    }

@@ -8664,6 +8670,7 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
        } else {
            mHalStream->stop();
        }
        eraseClientSilenceStateIfNoActiveClient_l(client.clientUid);
        return PERMISSION_DENIED;
    }

@@ -8671,6 +8678,9 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
    sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
                                        isOutput(), client.clientUid, client.clientPid,
                                        IPCThreadState::self()->getCallingPid(), portId);
    if (!isOutput()) {
        track->setSilenced_l(isClientSilenced_l(client.clientUid));
    }

    if (isOutput()) {
        // force volume update when a new track is added
@@ -8726,6 +8736,7 @@ status_t AudioFlinger::MmapThread::stop(audio_port_handle_t handle)
    }

    mActiveTracks.remove(track);
    eraseClientSilenceStateIfNoActiveClient_l(track->uid());

    mLock.unlock();
    if (isOutput()) {
@@ -9488,6 +9499,7 @@ void AudioFlinger::MmapCaptureThread::setRecordSilenced(uid_t uid, bool silenced
            broadcast_l();
        }
    }
    setClientSilencedIfExists_l(uid, silenced);
}

void AudioFlinger::MmapCaptureThread::toAudioPortConfig(struct audio_port_config *config)
+30 −0
Original line number Diff line number Diff line
@@ -1786,6 +1786,35 @@ class MmapThread : public ThreadBase
                // Sets the UID records silence
    virtual     void        setRecordSilenced(uid_t uid __unused, bool silenced __unused) {}

                void        setClientSilencedStateIfNotExist_l(uid_t uid, bool silenced) {
                                if (mClientSilencedStates.count(uid) == 0) {
                                    mClientSilencedStates[uid] = silenced;
                                }
                            }

                size_t      eraseClientSilenceStateIfNoActiveClient_l(uid_t uid) {
                                bool found = false;
                                for (const auto& t : mActiveTracks) {
                                    if (t->uid() == uid) {
                                        found = true;
                                    }
                                }
                                // Only erase when there is no active client for the given uid.
                                return found ? 0 : mClientSilencedStates.erase(uid);
                            }

                bool        isClientSilenced_l(uid_t uid) const {
                                const auto it = mClientSilencedStates.find(uid);
                                return it != mClientSilencedStates.end() ? it->second : false;
                            }

                void        setClientSilencedIfExists_l(uid_t uid, bool silenced) {
                                const auto it = mClientSilencedStates.find(uid);
                                if (it != mClientSilencedStates.end()) {
                                    it->second = silenced;
                                }
                            }

 protected:
                void        dumpInternals_l(int fd, const Vector<String16>& args) override;
                void        dumpTracks_l(int fd, const Vector<String16>& args) override;
@@ -1800,6 +1829,7 @@ class MmapThread : public ThreadBase
                AudioHwDevice* const    mAudioHwDev;
                ActiveTracks<MmapTrack> mActiveTracks;
                float                   mHalVolFloat;
                std::map<uid_t, bool>   mClientSilencedStates;

                int32_t                 mNoCallbackWarningCount;
     static     constexpr int32_t       kMaxNoCallbackWarnings = 5;