CSD: enable CSD for MMap threads

Using the buffer provided by the AAudio service to add values to the
sound dosage.

Test: OboeTester with AAudio and MMap
Bug: 264254430
Change-Id: I38b7d3b69bc8d6923f848bc504c6290ae1961cbc
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3b73333..27428b9 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3679,6 +3679,20 @@
     return thread;
 }
 
+// checkOutputThread_l() must be called with AudioFlinger::mLock held
+sp<AudioFlinger::ThreadBase> AudioFlinger::checkOutputThread_l(audio_io_handle_t ioHandle) const
+{
+    if (audio_unique_id_get_use(ioHandle) != AUDIO_UNIQUE_ID_USE_OUTPUT) {
+        return nullptr;
+    }
+
+    sp<AudioFlinger::ThreadBase> thread = mPlaybackThreads.valueFor(ioHandle);
+    if (thread == nullptr) {
+        thread = mMmapThreads.valueFor(ioHandle);
+    }
+    return thread;
+}
+
 // checkPlaybackThread_l() must be called with AudioFlinger::mLock held
 AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
 {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 876acbc..2204f8f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -764,6 +764,8 @@
     };
 
               ThreadBase *checkThread_l(audio_io_handle_t ioHandle) const;
+              sp<AudioFlinger::ThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const
+                      REQUIRES(mLock);
               PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const;
               MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
               RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index cfa02bb..52af56f 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -170,8 +170,8 @@
 }
 
 void AudioFlinger::MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch) {
-    auto thread = mAudioFlinger.checkPlaybackThread_l(patch.streamHandle);
-    if (thread == nullptr) {
+    auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
+    if (outputThread == nullptr) {
         ALOGE("%s cannot find thread for stream handle %d", __func__, patch.streamHandle);
         return;
     }
@@ -180,13 +180,16 @@
         ++mActiveDevices[deviceHandle];
         ALOGI("%s add stream %d that uses device %d for CSD, nr of streams: %d", __func__,
               patch.streamHandle, deviceHandle, mActiveDevices[deviceHandle]);
-        thread->startMelComputation(mSoundDoseManager->getOrCreateProcessorForDevice(
-            deviceHandle,
-            patch.streamHandle,
-            thread->mSampleRate,
-            thread->mChannelCount,
-            thread->mFormat));
+
+        if (outputThread != nullptr) {
+            outputThread->startMelComputation_l(mSoundDoseManager->getOrCreateProcessorForDevice(
+                deviceHandle,
+                patch.streamHandle,
+                outputThread->mSampleRate,
+                outputThread->mChannelCount,
+                outputThread->mFormat));
         }
+    }
 }
 
 void AudioFlinger::MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) {
@@ -229,7 +232,8 @@
         return;
     }
 
-    auto thread = mAudioFlinger.checkPlaybackThread_l(patch.streamHandle);
+   auto outputThread = mAudioFlinger.checkOutputThread_l(patch.streamHandle);
+
     ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle);
     for (const auto& deviceId : patch.deviceHandles) {
         if (mActiveDevices[deviceId] > 0) {
@@ -243,8 +247,8 @@
     }
 
     mSoundDoseManager->removeStreamProcessor(patch.streamHandle);
-    if (thread != nullptr) {
-        thread->stopMelComputation();
+    if (outputThread != nullptr) {
+        outputThread->stopMelComputation_l();
     }
 }
 
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0f65aec..743f94b 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2045,6 +2045,21 @@
     return AudioSystem::getStrategyForStream(stream);
 }
 
+// startMelComputation_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::ThreadBase::startMelComputation_l(
+        const sp<audio_utils::MelProcessor>& /*processor*/)
+{
+    // Do nothing
+    ALOGW("%s: ThreadBase does not support CSD", __func__);
+}
+
+// stopMelComputation_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::ThreadBase::stopMelComputation_l()
+{
+    // Do nothing
+    ALOGW("%s: ThreadBase does not support CSD", __func__);
+}
+
 // ----------------------------------------------------------------------------
 //      Playback
 // ----------------------------------------------------------------------------
@@ -3470,14 +3485,16 @@
     return bytesWritten;
 }
 
-void AudioFlinger::PlaybackThread::startMelComputation(
+// startMelComputation_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::PlaybackThread::startMelComputation_l(
         const sp<audio_utils::MelProcessor>& processor)
 {
     auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
     outputSink->startMelComputation(processor);
 }
 
-void AudioFlinger::PlaybackThread::stopMelComputation()
+// stopMelComputation_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::PlaybackThread::stopMelComputation_l()
 {
     auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
     outputSink->stopMelComputation();
@@ -10135,7 +10152,6 @@
     return INVALID_OPERATION;
 }
 
-
 void AudioFlinger::MmapThread::readHalParameters_l()
 {
     status_t result = mHalStream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat);
@@ -10818,12 +10834,32 @@
 }
 
 status_t AudioFlinger::MmapPlaybackThread::reportData(const void* buffer, size_t frameCount) {
-    // TODO(264254430): send the data to mel processor.
-    (void) buffer;
-    (void) frameCount;
+    // Send to MelProcessor for sound dose measurement.
+    auto processor = mMelProcessor.load();
+    if (processor) {
+        processor->process(buffer, frameCount * mFrameSize);
+    }
+
     return NO_ERROR;
 }
 
+// startMelComputation_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MmapPlaybackThread::startMelComputation_l(
+        const sp<audio_utils::MelProcessor>& processor)
+{
+    ALOGV("%s: starting mel processor for thread %d", __func__, id());
+    if (processor != nullptr) {
+        mMelProcessor = processor;
+    }
+}
+
+// stopMelComputation_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MmapPlaybackThread::stopMelComputation_l()
+{
+    ALOGV("%s: stopping mel processor for thread %d", __func__, id());
+    mMelProcessor = nullptr;
+}
+
 void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
 {
     MmapThread::dumpInternals_l(fd, args);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index f0062bc..03e4567 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -576,6 +576,9 @@
 
     virtual     bool isStreamInitialized() = 0;
 
+    virtual     void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor);
+    virtual     void stopMelComputation_l();
+
 protected:
 
                 // entry describing an effect being suspended in mSuspendedSessions keyed vector
@@ -1110,8 +1113,8 @@
                     return INVALID_OPERATION;
                 }
 
-                void startMelComputation(const sp<audio_utils::MelProcessor>& processor);
-                void stopMelComputation();
+                void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
+                void stopMelComputation_l() override;
 
 protected:
     // updated by readOutputParameters_l()
@@ -2273,6 +2276,9 @@
 
                 status_t    reportData(const void* buffer, size_t frameCount) override;
 
+                void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
+                void stopMelComputation_l() override;
+
 protected:
                 void        dumpInternals_l(int fd, const Vector<String16>& args) override;
 
@@ -2282,6 +2288,8 @@
                 bool                        mMasterMute;
                 bool                        mStreamMute;
                 AudioStreamOut*             mOutput;
+
+                mediautils::atomic_sp<audio_utils::MelProcessor> mMelProcessor;
 };
 
 class MmapCaptureThread : public MmapThread