CSD: add logic for using HAL sound dose values

When the HAL supports the sound dose computation we prefer to use the
MEL value provided by the HAL. These should be more accurate and can be
used for certification with IEC62368-1 3rd edition and EN50332-3.
Current implementation supports the standalone sound dose HAL.

Test: sounddosemanager_tests UT & bluejay-userdebug with internal MEL
Bug: 252776298
Change-Id: Ibbda76781fc869ac457d03d4f9a871fb353a9ba8
diff --git a/services/audioflinger/sounddose/SoundDoseManager.h b/services/audioflinger/sounddose/SoundDoseManager.h
index eb5fa49..199e8c9 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.h
+++ b/services/audioflinger/sounddose/SoundDoseManager.h
@@ -17,8 +17,11 @@
 
 #pragma once
 
+#include <aidl/android/hardware/audio/core/ISoundDose.h>
+#include <aidl/android/media/audio/common/AudioDevice.h>
 #include <android/media/BnSoundDose.h>
 #include <android/media/ISoundDoseCallback.h>
+#include <media/AudioDeviceTypeAddr.h>
 #include <audio_utils/MelAggregator.h>
 #include <audio_utils/MelProcessor.h>
 #include <binder/Status.h>
@@ -27,8 +30,10 @@
 
 namespace android {
 
+using aidl::android::hardware::audio::core::ISoundDose;
+
 class SoundDoseManager : public audio_utils::MelProcessor::MelCallback {
-  public:
+public:
     /** CSD is computed with a rolling window of 7 days. */
     static constexpr int64_t kCsdWindowSeconds = 604800;  // 60s * 60m * 24h * 7d
     /** Default RS2 value in dBA as defined in IEC 62368-1 3rd edition. */
@@ -36,13 +41,13 @@
 
     SoundDoseManager()
         : mMelAggregator(sp<audio_utils::MelAggregator>::make(kCsdWindowSeconds)),
-          mRs2Value(kDefaultRs2Value){};
+          mRs2Value(kDefaultRs2Value) {};
 
     /**
      * \brief Creates or gets the MelProcessor assigned to the streamHandle
      *
      * \param deviceId          id for the devices where the stream is active.
-     * \param streanHandle      handle to the stream
+     * \param streamHandle      handle to the stream
      * \param sampleRate        sample rate for the processor
      * \param channelCount      number of channels to be processed.
      * \param format            format of the input samples.
@@ -58,7 +63,7 @@
     /**
      * \brief Removes stream processor when MEL computation is not needed anymore
      *
-     * \param streanHandle      handle to the stream
+     * \param streamHandle      handle to the stream
      */
     void removeStreamProcessor(audio_io_handle_t streamHandle);
 
@@ -78,6 +83,25 @@
      **/
     sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback);
 
+    /**
+     * Sets the HAL sound dose interface to use for the MEL computation. Use nullptr
+     * for using the internal MEL computation.
+     *
+     * @return true if setting the HAL sound dose value was successful, false otherwise.
+     */
+    bool setHalSoundDoseInterface(const std::shared_ptr<ISoundDose>& halSoundDose);
+
+    /** Returns the cached audio port id from the active devices. */
+    audio_port_handle_t getIdForAudioDevice(
+            const aidl::android::media::audio::common::AudioDevice& audioDevice) const;
+
+    /** Caches mapping between address and device port id. */
+    void mapAddressToDeviceId(const AudioDeviceTypeAddr& adt,
+                              const audio_port_handle_t deviceId);
+
+    /** Clear all map entries with passed audio_port_handle_t. */
+    void clearMapDeviceIdEntries(audio_port_handle_t deviceId);
+
     std::string dump() const;
 
     // used for testing
@@ -101,7 +125,7 @@
     public:
         SoundDose(SoundDoseManager* manager, const sp<media::ISoundDoseCallback>& callback)
             : mSoundDoseManager(manager),
-              mSoundDoseCallback(callback) {};
+              mSoundDoseCallback(callback) {}
 
         /** IBinder::DeathRecipient. Listen to the death of ISoundDoseCallback. */
         virtual void binderDied(const wp<IBinder>& who);
@@ -119,6 +143,21 @@
         const sp<media::ISoundDoseCallback> mSoundDoseCallback;
     };
 
+    class HalSoundDoseCallback : public ISoundDose::BnHalSoundDoseCallback {
+    public:
+        explicit HalSoundDoseCallback(SoundDoseManager* manager)
+            : mSoundDoseManager(manager) {}
+
+        ndk::ScopedAStatus onMomentaryExposureWarning(
+                float in_currentDbA,
+                const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
+        ndk::ScopedAStatus onNewMelValues(
+                const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
+                const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
+
+        wp<SoundDoseManager> mSoundDoseManager;
+    };
+
     void resetSoundDose();
 
     void resetCsd(float currentCsd, const std::vector<media::SoundDoseRecord>& records);
@@ -136,10 +175,16 @@
     std::unordered_map<audio_io_handle_t, wp<audio_utils::MelProcessor>> mActiveProcessors
             GUARDED_BY(mLock);
 
+    // map active device address and type to device id
+    std::map<AudioDeviceTypeAddr, audio_port_handle_t> mActiveDevices GUARDED_BY(mLock);
+
     float mRs2Value GUARDED_BY(mLock);
 
     sp<SoundDose> mSoundDose GUARDED_BY(mLock);
 
+    std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock);
+    std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock);
+
     bool mUseFrameworkMel GUARDED_BY(mLock);
     bool mComputeCsdOnAllDevices GUARDED_BY(mLock);
 };