CSD: Enable the CSD only for MUSIC and GAME usage

Any mix that contain a track with MUSIC and GAME usage can have an
active CSD computation. This is a requirement of the IEC62368-1 3rd
edition and EN50332-3.

Also implemented logic to ignore the HAL MELs when there is no active
stream with MUSIC/GAME usage on the device that reports the values.

Test: dumpsys media.audio_flinger and logs
Bug: 265936306
Change-Id: I583de61c6917823522557ae5c1371d9242a273cb
diff --git a/services/audioflinger/MelReporter.h b/services/audioflinger/MelReporter.h
index 5e7f0cc..c1b291f 100644
--- a/services/audioflinger/MelReporter.h
+++ b/services/audioflinger/MelReporter.h
@@ -37,9 +37,6 @@
 
     void onFirstRef() override;
 
-    /** Returns true if we should compute MEL for the given device. */
-    bool shouldComputeMelForDeviceType(audio_devices_t device);
-
     /**
      * Activates the MEL reporting from the HAL sound dose interface. If the HAL
      * does not support the sound dose interface for this module, the internal MEL
@@ -73,22 +70,39 @@
                             const PatchPanel::Patch& patch) override;
     void onReleaseAudioPatch(audio_patch_handle_t handle) override;
 
+    /**
+     * The new metadata can determine whether we should compute MEL for the given thread.
+     * This is the case only if one of the tracks in the thread mix is using MEDIA or GAME.
+     * Otherwise, this method will disable CSD.
+     **/
+    void updateMetadataForCsd(audio_io_handle_t streamHandle,
+                              const std::vector<playback_track_metadata_v7_t>& metadataVec);
 private:
-    void stopInternalMelComputation();
-    void stopInternalMelComputationForStream(audio_io_handle_t streamId);
+    struct ActiveMelPatch {
+        audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE};
+        std::vector<audio_port_handle_t> deviceHandles;
+        bool csdActive;
+    };
 
-    void startMelComputationForNewPatch(audio_io_handle_t streamHandle,
-                                        audio_port_handle_t deviceId);
+    /** Returns true if we should compute MEL for the given device. */
+    bool shouldComputeMelForDeviceType(audio_devices_t device);
+
+    void stopInternalMelComputation();
+
+    /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */
+    void stopMelComputationForPatch_l(const ActiveMelPatch& patch);
+
+    /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */
+    void startMelComputationForActivePatch_l(const ActiveMelPatch& patch);
+
+    std::optional<audio_patch_handle_t> activePatchStreamHandle_l(audio_io_handle_t streamHandle);
+
+    bool useHalSoundDoseInterface();
 
     AudioFlinger& mAudioFlinger;  // does not own the object
 
     sp<SoundDoseManager> mSoundDoseManager;
 
-    struct ActiveMelPatch {
-        audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE};
-        std::vector<audio_port_handle_t> deviceHandles;
-    };
-
     /**
      * Lock for protecting the active mel patches. Do not mix with the AudioFlinger lock.
      * Locking order AudioFlinger::mLock -> PatchCommandThread::mLock -> MelReporter::mLock.
@@ -96,5 +110,7 @@
     std::mutex mLock;
     std::unordered_map<audio_patch_handle_t, ActiveMelPatch>
         mActiveMelPatches GUARDED_BY(AudioFlinger::MelReporter::mLock);
+    std::unordered_map<audio_port_handle_t, int>
+        mActiveDevices GUARDED_BY(AudioFlinger::MelReporter::mLock);
     bool mUseHalSoundDoseInterface GUARDED_BY(AudioFlinger::MelReporter::mLock) = false;
 };