1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker ** 3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2022, The Android Open Source Project 4*ec779b8eSAndroid Build Coastguard Worker ** 5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License"); 6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License. 7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at 8*ec779b8eSAndroid Build Coastguard Worker ** 9*ec779b8eSAndroid Build Coastguard Worker ** http://www.apache.org/licenses/LICENSE-2.0 10*ec779b8eSAndroid Build Coastguard Worker ** 11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software 12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS, 13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and 15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License. 16*ec779b8eSAndroid Build Coastguard Worker */ 17*ec779b8eSAndroid Build Coastguard Worker 18*ec779b8eSAndroid Build Coastguard Worker #pragma once 19*ec779b8eSAndroid Build Coastguard Worker 20*ec779b8eSAndroid Build Coastguard Worker #include "IAfPatchPanel.h" 21*ec779b8eSAndroid Build Coastguard Worker #include "PatchCommandThread.h" 22*ec779b8eSAndroid Build Coastguard Worker 23*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/mutex.h> 24*ec779b8eSAndroid Build Coastguard Worker #include <sounddose/SoundDoseManager.h> 25*ec779b8eSAndroid Build Coastguard Worker 26*ec779b8eSAndroid Build Coastguard Worker #include <unordered_map> 27*ec779b8eSAndroid Build Coastguard Worker 28*ec779b8eSAndroid Build Coastguard Worker namespace android { 29*ec779b8eSAndroid Build Coastguard Worker 30*ec779b8eSAndroid Build Coastguard Worker class IAfMelReporterCallback : public virtual RefBase { 31*ec779b8eSAndroid Build Coastguard Worker public: 32*ec779b8eSAndroid Build Coastguard Worker virtual audio_utils::mutex& mutex() const 33*ec779b8eSAndroid Build Coastguard Worker RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0; 34*ec779b8eSAndroid Build Coastguard Worker virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0; 35*ec779b8eSAndroid Build Coastguard Worker virtual sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const 36*ec779b8eSAndroid Build Coastguard Worker REQUIRES(mutex()) = 0; 37*ec779b8eSAndroid Build Coastguard Worker }; 38*ec779b8eSAndroid Build Coastguard Worker 39*ec779b8eSAndroid Build Coastguard Worker /** 40*ec779b8eSAndroid Build Coastguard Worker * Class for listening to new patches and starting the MEL computation. MelReporter is 41*ec779b8eSAndroid Build Coastguard Worker * concealed within AudioFlinger, their lifetimes are the same. 42*ec779b8eSAndroid Build Coastguard Worker */ 43*ec779b8eSAndroid Build Coastguard Worker class MelReporter : public PatchCommandThread::PatchCommandListener, 44*ec779b8eSAndroid Build Coastguard Worker public IMelReporterCallback { 45*ec779b8eSAndroid Build Coastguard Worker public: MelReporter(const sp<IAfMelReporterCallback> & afMelReporterCallback,const sp<IAfPatchPanel> & afPatchPanel)46*ec779b8eSAndroid Build Coastguard Worker MelReporter(const sp<IAfMelReporterCallback>& afMelReporterCallback, 47*ec779b8eSAndroid Build Coastguard Worker const sp<IAfPatchPanel>& afPatchPanel) 48*ec779b8eSAndroid Build Coastguard Worker : mAfMelReporterCallback(afMelReporterCallback), 49*ec779b8eSAndroid Build Coastguard Worker mAfPatchPanel(afPatchPanel) {} 50*ec779b8eSAndroid Build Coastguard Worker 51*ec779b8eSAndroid Build Coastguard Worker void onFirstRef() override; 52*ec779b8eSAndroid Build Coastguard Worker 53*ec779b8eSAndroid Build Coastguard Worker /** 54*ec779b8eSAndroid Build Coastguard Worker * Activates the MEL reporting from the HAL sound dose interface. If the HAL 55*ec779b8eSAndroid Build Coastguard Worker * does not support the sound dose interface for this module, the internal MEL 56*ec779b8eSAndroid Build Coastguard Worker * calculation will be use. 57*ec779b8eSAndroid Build Coastguard Worker * 58*ec779b8eSAndroid Build Coastguard Worker * <p>If the device is using the audio AIDL HAL then this method will try to get the sound 59*ec779b8eSAndroid Build Coastguard Worker * dose interface from IModule#getSoundDose(). Otherwise, if the legacy audio HIDL HAL is used 60*ec779b8eSAndroid Build Coastguard Worker * this method will be looking for the standalone sound dose implementation. It falls back to 61*ec779b8eSAndroid Build Coastguard Worker * the internal MEL computation if no valid sound dose interface can be retrieved. 62*ec779b8eSAndroid Build Coastguard Worker * 63*ec779b8eSAndroid Build Coastguard Worker * @return true if the MEL reporting will be done from any sound dose HAL interface 64*ec779b8eSAndroid Build Coastguard Worker * implementation, false otherwise. 65*ec779b8eSAndroid Build Coastguard Worker */ 66*ec779b8eSAndroid Build Coastguard Worker bool activateHalSoundDoseComputation(const std::string& module, 67*ec779b8eSAndroid Build Coastguard Worker const sp<DeviceHalInterface>& device) EXCLUDES_MelReporter_Mutex; 68*ec779b8eSAndroid Build Coastguard Worker 69*ec779b8eSAndroid Build Coastguard Worker /** 70*ec779b8eSAndroid Build Coastguard Worker * Activates the MEL reporting from internal framework values. These are used 71*ec779b8eSAndroid Build Coastguard Worker * as a fallback when there is no sound dose interface implementation from HAL. 72*ec779b8eSAndroid Build Coastguard Worker * Note: the internal CSD computation does not guarantee a certification with 73*ec779b8eSAndroid Build Coastguard Worker * IEC62368-1 3rd edition or EN50332-3 74*ec779b8eSAndroid Build Coastguard Worker */ 75*ec779b8eSAndroid Build Coastguard Worker void activateInternalSoundDoseComputation() EXCLUDES_MelReporter_Mutex; 76*ec779b8eSAndroid Build Coastguard Worker 77*ec779b8eSAndroid Build Coastguard Worker sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback); 78*ec779b8eSAndroid Build Coastguard Worker 79*ec779b8eSAndroid Build Coastguard Worker std::string dump(); 80*ec779b8eSAndroid Build Coastguard Worker 81*ec779b8eSAndroid Build Coastguard Worker // IMelReporterCallback methods 82*ec779b8eSAndroid Build Coastguard Worker void stopMelComputationForDeviceId(audio_port_handle_t deviceId) final 83*ec779b8eSAndroid Build Coastguard Worker EXCLUDES_AudioFlinger_Mutex EXCLUDES_MelReporter_Mutex; 84*ec779b8eSAndroid Build Coastguard Worker void startMelComputationForDeviceId(audio_port_handle_t deviceId) final 85*ec779b8eSAndroid Build Coastguard Worker EXCLUDES_AudioFlinger_Mutex EXCLUDES_MelReporter_Mutex; 86*ec779b8eSAndroid Build Coastguard Worker void applyAllAudioPatches() final EXCLUDES_AudioFlinger_Mutex EXCLUDES_MelReporter_Mutex; 87*ec779b8eSAndroid Build Coastguard Worker 88*ec779b8eSAndroid Build Coastguard Worker // PatchCommandListener methods 89*ec779b8eSAndroid Build Coastguard Worker void onCreateAudioPatch(audio_patch_handle_t handle, 90*ec779b8eSAndroid Build Coastguard Worker const IAfPatchPanel::Patch& patch) final 91*ec779b8eSAndroid Build Coastguard Worker EXCLUDES_AudioFlinger_Mutex; 92*ec779b8eSAndroid Build Coastguard Worker void onReleaseAudioPatch(audio_patch_handle_t handle) final EXCLUDES_AudioFlinger_Mutex; 93*ec779b8eSAndroid Build Coastguard Worker void onUpdateAudioPatch(audio_patch_handle_t oldHandle, 94*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t newHandle, 95*ec779b8eSAndroid Build Coastguard Worker const IAfPatchPanel::Patch& patch) final EXCLUDES_AudioFlinger_Mutex; 96*ec779b8eSAndroid Build Coastguard Worker 97*ec779b8eSAndroid Build Coastguard Worker /** 98*ec779b8eSAndroid Build Coastguard Worker * The new metadata can determine whether we should compute MEL for the given thread. 99*ec779b8eSAndroid Build Coastguard Worker * This is the case only if one of the tracks in the thread mix is using MEDIA or GAME. 100*ec779b8eSAndroid Build Coastguard Worker * Otherwise, this method will disable CSD. 101*ec779b8eSAndroid Build Coastguard Worker **/ 102*ec779b8eSAndroid Build Coastguard Worker void updateMetadataForCsd(audio_io_handle_t streamHandle, 103*ec779b8eSAndroid Build Coastguard Worker const std::vector<playback_track_metadata_v7_t>& metadataVec) 104*ec779b8eSAndroid Build Coastguard Worker EXCLUDES_AudioFlinger_Mutex; 105*ec779b8eSAndroid Build Coastguard Worker 106*ec779b8eSAndroid Build Coastguard Worker void resetReferencesForTest(); 107*ec779b8eSAndroid Build Coastguard Worker 108*ec779b8eSAndroid Build Coastguard Worker private: 109*ec779b8eSAndroid Build Coastguard Worker struct ActiveMelPatch { 110*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE}; 111*ec779b8eSAndroid Build Coastguard Worker /** 112*ec779b8eSAndroid Build Coastguard Worker * Stores device ids and whether they are compatible for CSD calculation. 113*ec779b8eSAndroid Build Coastguard Worker * The boolean value can change since BT audio device types are user-configurable 114*ec779b8eSAndroid Build Coastguard Worker * to headphones/headsets or other device types. 115*ec779b8eSAndroid Build Coastguard Worker */ 116*ec779b8eSAndroid Build Coastguard Worker std::vector<std::pair<audio_port_handle_t,bool>> deviceStates; 117*ec779b8eSAndroid Build Coastguard Worker bool csdActive; 118*ec779b8eSAndroid Build Coastguard Worker }; 119*ec779b8eSAndroid Build Coastguard Worker 120*ec779b8eSAndroid Build Coastguard Worker void stopInternalMelComputation(); mutex()121*ec779b8eSAndroid Build Coastguard Worker audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::MelReporter_Mutex) { 122*ec779b8eSAndroid Build Coastguard Worker return mMutex; 123*ec779b8eSAndroid Build Coastguard Worker } 124*ec779b8eSAndroid Build Coastguard Worker 125*ec779b8eSAndroid Build Coastguard Worker /** Should be called with the following order of locks: mAudioFlinger.mutex() -> mutex(). */ 126*ec779b8eSAndroid Build Coastguard Worker void stopMelComputationForPatch_l(const ActiveMelPatch& patch) REQUIRES(mutex()); 127*ec779b8eSAndroid Build Coastguard Worker 128*ec779b8eSAndroid Build Coastguard Worker /** Should be called with the following order of locks: mAudioFlinger.mutex() -> mutex(). */ 129*ec779b8eSAndroid Build Coastguard Worker void startMelComputationForActivePatch_l(const ActiveMelPatch& patch) REQUIRES(mutex()); 130*ec779b8eSAndroid Build Coastguard Worker 131*ec779b8eSAndroid Build Coastguard Worker std::optional<audio_patch_handle_t> 132*ec779b8eSAndroid Build Coastguard Worker activePatchStreamHandle_l(audio_io_handle_t streamHandle) REQUIRES(mutex()); 133*ec779b8eSAndroid Build Coastguard Worker 134*ec779b8eSAndroid Build Coastguard Worker bool useHalSoundDoseInterface_l() REQUIRES(mutex()); 135*ec779b8eSAndroid Build Coastguard Worker 136*ec779b8eSAndroid Build Coastguard Worker sp<IAfMelReporterCallback> mAfMelReporterCallback; 137*ec779b8eSAndroid Build Coastguard Worker const sp<IAfPatchPanel> mAfPatchPanel; 138*ec779b8eSAndroid Build Coastguard Worker 139*ec779b8eSAndroid Build Coastguard Worker /* const */ sp<SoundDoseManager> mSoundDoseManager; // set onFirstRef 140*ec779b8eSAndroid Build Coastguard Worker 141*ec779b8eSAndroid Build Coastguard Worker /** 142*ec779b8eSAndroid Build Coastguard Worker * Lock for protecting the active mel patches. Do not mix with the AudioFlinger lock. 143*ec779b8eSAndroid Build Coastguard Worker * Locking order AudioFlinger::mutex() -> PatchCommandThread::mutex() -> MelReporter::mutex(). 144*ec779b8eSAndroid Build Coastguard Worker */ 145*ec779b8eSAndroid Build Coastguard Worker mutable audio_utils::mutex mMutex{audio_utils::MutexOrder::kMelReporter_Mutex}; 146*ec779b8eSAndroid Build Coastguard Worker std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches 147*ec779b8eSAndroid Build Coastguard Worker GUARDED_BY(mutex()); 148*ec779b8eSAndroid Build Coastguard Worker std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(mutex()); 149*ec779b8eSAndroid Build Coastguard Worker bool mUseHalSoundDoseInterface GUARDED_BY(mutex()) = false; 150*ec779b8eSAndroid Build Coastguard Worker }; 151*ec779b8eSAndroid Build Coastguard Worker 152*ec779b8eSAndroid Build Coastguard Worker } // namespace android 153