xref: /aosp_15_r20/frameworks/av/services/audioflinger/MelReporter.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 // #define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "MelReporter"
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include "MelReporter.h"
22*ec779b8eSAndroid Build Coastguard Worker 
23*ec779b8eSAndroid Build Coastguard Worker #include <android/media/ISoundDoseCallback.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/power.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::sounddose::ISoundDose;
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker namespace android {
30*ec779b8eSAndroid Build Coastguard Worker 
activateHalSoundDoseComputation(const std::string & module,const sp<DeviceHalInterface> & device)31*ec779b8eSAndroid Build Coastguard Worker bool MelReporter::activateHalSoundDoseComputation(const std::string& module,
32*ec779b8eSAndroid Build Coastguard Worker         const sp<DeviceHalInterface>& device) {
33*ec779b8eSAndroid Build Coastguard Worker     if (mSoundDoseManager->isFrameworkMelForced()) {
34*ec779b8eSAndroid Build Coastguard Worker         ALOGD("%s: Forcing use of internal MEL computation.", __func__);
35*ec779b8eSAndroid Build Coastguard Worker         activateInternalSoundDoseComputation();
36*ec779b8eSAndroid Build Coastguard Worker         return false;
37*ec779b8eSAndroid Build Coastguard Worker     }
38*ec779b8eSAndroid Build Coastguard Worker 
39*ec779b8eSAndroid Build Coastguard Worker     ndk::SpAIBinder soundDoseBinder;
40*ec779b8eSAndroid Build Coastguard Worker     if (device->getSoundDoseInterface(module, &soundDoseBinder) != OK) {
41*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: HAL cannot provide sound dose interface for module %s",
42*ec779b8eSAndroid Build Coastguard Worker               __func__, module.c_str());
43*ec779b8eSAndroid Build Coastguard Worker         return false;
44*ec779b8eSAndroid Build Coastguard Worker     }
45*ec779b8eSAndroid Build Coastguard Worker 
46*ec779b8eSAndroid Build Coastguard Worker     if (soundDoseBinder == nullptr) {
47*ec779b8eSAndroid Build Coastguard Worker          ALOGW("%s: HAL doesn't implement a sound dose interface for module %s",
48*ec779b8eSAndroid Build Coastguard Worker               __func__, module.c_str());
49*ec779b8eSAndroid Build Coastguard Worker         return false;
50*ec779b8eSAndroid Build Coastguard Worker     }
51*ec779b8eSAndroid Build Coastguard Worker 
52*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<ISoundDose> soundDoseInterface = ISoundDose::fromBinder(soundDoseBinder);
53*ec779b8eSAndroid Build Coastguard Worker 
54*ec779b8eSAndroid Build Coastguard Worker     if (!mSoundDoseManager->setHalSoundDoseInterface(module, soundDoseInterface)) {
55*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: cannot activate HAL MEL reporting for module %s", __func__, module.c_str());
56*ec779b8eSAndroid Build Coastguard Worker         return false;
57*ec779b8eSAndroid Build Coastguard Worker     }
58*ec779b8eSAndroid Build Coastguard Worker 
59*ec779b8eSAndroid Build Coastguard Worker     stopInternalMelComputation();
60*ec779b8eSAndroid Build Coastguard Worker     return true;
61*ec779b8eSAndroid Build Coastguard Worker }
62*ec779b8eSAndroid Build Coastguard Worker 
activateInternalSoundDoseComputation()63*ec779b8eSAndroid Build Coastguard Worker void MelReporter::activateInternalSoundDoseComputation() {
64*ec779b8eSAndroid Build Coastguard Worker     {
65*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
66*ec779b8eSAndroid Build Coastguard Worker         if (!mUseHalSoundDoseInterface) {
67*ec779b8eSAndroid Build Coastguard Worker             // no need to start internal MEL on active patches
68*ec779b8eSAndroid Build Coastguard Worker             return;
69*ec779b8eSAndroid Build Coastguard Worker         }
70*ec779b8eSAndroid Build Coastguard Worker         mUseHalSoundDoseInterface = false;
71*ec779b8eSAndroid Build Coastguard Worker     }
72*ec779b8eSAndroid Build Coastguard Worker 
73*ec779b8eSAndroid Build Coastguard Worker     // reset the HAL interfaces and use internal MELs
74*ec779b8eSAndroid Build Coastguard Worker     mSoundDoseManager->resetHalSoundDoseInterfaces();
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker 
onFirstRef()77*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onFirstRef() {
78*ec779b8eSAndroid Build Coastguard Worker     mAfMelReporterCallback->getPatchCommandThread()->addListener(this);
79*ec779b8eSAndroid Build Coastguard Worker 
80*ec779b8eSAndroid Build Coastguard Worker     mSoundDoseManager = sp<SoundDoseManager>::make(sp<IMelReporterCallback>::fromExisting(this));
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker 
updateMetadataForCsd(audio_io_handle_t streamHandle,const std::vector<playback_track_metadata_v7_t> & metadataVec)83*ec779b8eSAndroid Build Coastguard Worker void MelReporter::updateMetadataForCsd(audio_io_handle_t streamHandle,
84*ec779b8eSAndroid Build Coastguard Worker         const std::vector<playback_track_metadata_v7_t>& metadataVec) {
85*ec779b8eSAndroid Build Coastguard Worker     if (!mSoundDoseManager->isCsdEnabled()) {
86*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s csd is disabled", __func__);
87*ec779b8eSAndroid Build Coastguard Worker         return;
88*ec779b8eSAndroid Build Coastguard Worker     }
89*ec779b8eSAndroid Build Coastguard Worker 
90*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());  // AudioFlinger_Mutex
91*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
92*ec779b8eSAndroid Build Coastguard Worker     auto activeMelPatchId = activePatchStreamHandle_l(streamHandle);
93*ec779b8eSAndroid Build Coastguard Worker     if (!activeMelPatchId) {
94*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s stream handle %d does not have an active patch", __func__, streamHandle);
95*ec779b8eSAndroid Build Coastguard Worker         return;
96*ec779b8eSAndroid Build Coastguard Worker     }
97*ec779b8eSAndroid Build Coastguard Worker 
98*ec779b8eSAndroid Build Coastguard Worker     bool shouldActivateCsd = false;
99*ec779b8eSAndroid Build Coastguard Worker     for (const auto& metadata : metadataVec) {
100*ec779b8eSAndroid Build Coastguard Worker         if (metadata.base.usage == AUDIO_USAGE_GAME || metadata.base.usage == AUDIO_USAGE_MEDIA) {
101*ec779b8eSAndroid Build Coastguard Worker             shouldActivateCsd = true;
102*ec779b8eSAndroid Build Coastguard Worker         }
103*ec779b8eSAndroid Build Coastguard Worker     }
104*ec779b8eSAndroid Build Coastguard Worker 
105*ec779b8eSAndroid Build Coastguard Worker     auto activeMelPatchIt = mActiveMelPatches.find(activeMelPatchId.value());
106*ec779b8eSAndroid Build Coastguard Worker     if (activeMelPatchIt != mActiveMelPatches.end()) {
107*ec779b8eSAndroid Build Coastguard Worker         if (shouldActivateCsd != activeMelPatchIt->second.csdActive) {
108*ec779b8eSAndroid Build Coastguard Worker             if (activeMelPatchIt->second.csdActive) {
109*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("%s should not compute CSD for stream handle %d", __func__, streamHandle);
110*ec779b8eSAndroid Build Coastguard Worker                 stopMelComputationForPatch_l(activeMelPatchIt->second);
111*ec779b8eSAndroid Build Coastguard Worker             } else {
112*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("%s should compute CSD for stream handle %d", __func__, streamHandle);
113*ec779b8eSAndroid Build Coastguard Worker                 startMelComputationForActivePatch_l(activeMelPatchIt->second);
114*ec779b8eSAndroid Build Coastguard Worker             }
115*ec779b8eSAndroid Build Coastguard Worker             activeMelPatchIt->second.csdActive = shouldActivateCsd;
116*ec779b8eSAndroid Build Coastguard Worker         }
117*ec779b8eSAndroid Build Coastguard Worker     }
118*ec779b8eSAndroid Build Coastguard Worker }
119*ec779b8eSAndroid Build Coastguard Worker 
resetReferencesForTest()120*ec779b8eSAndroid Build Coastguard Worker void MelReporter::resetReferencesForTest() {
121*ec779b8eSAndroid Build Coastguard Worker     mAfMelReporterCallback.clear();
122*ec779b8eSAndroid Build Coastguard Worker     mSoundDoseManager->resetReferencesForTest();
123*ec779b8eSAndroid Build Coastguard Worker }
124*ec779b8eSAndroid Build Coastguard Worker 
onCreateAudioPatch(audio_patch_handle_t handle,const IAfPatchPanel::Patch & patch)125*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onCreateAudioPatch(audio_patch_handle_t handle,
126*ec779b8eSAndroid Build Coastguard Worker         const IAfPatchPanel::Patch& patch) {
127*ec779b8eSAndroid Build Coastguard Worker     if (!mSoundDoseManager->isCsdEnabled()) {
128*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s csd is disabled", __func__);
129*ec779b8eSAndroid Build Coastguard Worker         return;
130*ec779b8eSAndroid Build Coastguard Worker     }
131*ec779b8eSAndroid Build Coastguard Worker 
132*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: handle %d mHalHandle %d device sink %08x",
133*ec779b8eSAndroid Build Coastguard Worker             __func__, handle, patch.mHalHandle,
134*ec779b8eSAndroid Build Coastguard Worker             patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
135*ec779b8eSAndroid Build Coastguard Worker     if (patch.mAudioPatch.num_sources == 0
136*ec779b8eSAndroid Build Coastguard Worker         || patch.mAudioPatch.sources[0].type != AUDIO_PORT_TYPE_MIX) {
137*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s: patch does not contain any mix sources", __func__);
138*ec779b8eSAndroid Build Coastguard Worker         return;
139*ec779b8eSAndroid Build Coastguard Worker     }
140*ec779b8eSAndroid Build Coastguard Worker 
141*ec779b8eSAndroid Build Coastguard Worker     audio_io_handle_t streamHandle = patch.mAudioPatch.sources[0].ext.mix.handle;
142*ec779b8eSAndroid Build Coastguard Worker     ActiveMelPatch newPatch;
143*ec779b8eSAndroid Build Coastguard Worker     newPatch.streamHandle = streamHandle;
144*ec779b8eSAndroid Build Coastguard Worker     newPatch.csdActive = false;
145*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < patch.mAudioPatch.num_sinks; ++i) {
146*ec779b8eSAndroid Build Coastguard Worker         if (patch.mAudioPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
147*ec779b8eSAndroid Build Coastguard Worker                 mSoundDoseManager->shouldComputeCsdForDeviceType(
148*ec779b8eSAndroid Build Coastguard Worker                         patch.mAudioPatch.sinks[i].ext.device.type)) {
149*ec779b8eSAndroid Build Coastguard Worker             audio_port_handle_t deviceId = patch.mAudioPatch.sinks[i].id;
150*ec779b8eSAndroid Build Coastguard Worker             bool shouldComputeCsd = mSoundDoseManager->shouldComputeCsdForDeviceWithAddress(
151*ec779b8eSAndroid Build Coastguard Worker                     patch.mAudioPatch.sinks[i].ext.device.type,
152*ec779b8eSAndroid Build Coastguard Worker                     patch.mAudioPatch.sinks[i].ext.device.address);
153*ec779b8eSAndroid Build Coastguard Worker             newPatch.deviceStates.push_back({deviceId, shouldComputeCsd});
154*ec779b8eSAndroid Build Coastguard Worker             newPatch.csdActive |= shouldComputeCsd;
155*ec779b8eSAndroid Build Coastguard Worker             AudioDeviceTypeAddr adt{patch.mAudioPatch.sinks[i].ext.device.type,
156*ec779b8eSAndroid Build Coastguard Worker                                     patch.mAudioPatch.sinks[i].ext.device.address};
157*ec779b8eSAndroid Build Coastguard Worker             mSoundDoseManager->mapAddressToDeviceId(adt, deviceId);
158*ec779b8eSAndroid Build Coastguard Worker         }
159*ec779b8eSAndroid Build Coastguard Worker     }
160*ec779b8eSAndroid Build Coastguard Worker 
161*ec779b8eSAndroid Build Coastguard Worker     if (!newPatch.deviceStates.empty() && newPatch.csdActive) {
162*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex());  // AudioFlinger_Mutex
163*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
164*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s add patch handle %d to active devices", __func__, handle);
165*ec779b8eSAndroid Build Coastguard Worker         startMelComputationForActivePatch_l(newPatch);
166*ec779b8eSAndroid Build Coastguard Worker         mActiveMelPatches[handle] = newPatch;
167*ec779b8eSAndroid Build Coastguard Worker     }
168*ec779b8eSAndroid Build Coastguard Worker }
169*ec779b8eSAndroid Build Coastguard Worker 
startMelComputationForActivePatch_l(const ActiveMelPatch & patch)170*ec779b8eSAndroid Build Coastguard Worker void MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch)
171*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS  // access of AudioFlinger::checkOutputThread_l
172*ec779b8eSAndroid Build Coastguard Worker {
173*ec779b8eSAndroid Build Coastguard Worker     auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
174*ec779b8eSAndroid Build Coastguard Worker     if (outputThread == nullptr) {
175*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s cannot find thread for stream handle %d", __func__, patch.streamHandle);
176*ec779b8eSAndroid Build Coastguard Worker         return;
177*ec779b8eSAndroid Build Coastguard Worker     }
178*ec779b8eSAndroid Build Coastguard Worker 
179*ec779b8eSAndroid Build Coastguard Worker     for (const auto& device : patch.deviceStates) {
180*ec779b8eSAndroid Build Coastguard Worker         if (device.second) {
181*ec779b8eSAndroid Build Coastguard Worker             ++mActiveDevices[device.first];
182*ec779b8eSAndroid Build Coastguard Worker             ALOGI("%s add stream %d that uses device %d for CSD, nr of streams: %d", __func__,
183*ec779b8eSAndroid Build Coastguard Worker                   patch.streamHandle, device.first, mActiveDevices[device.first]);
184*ec779b8eSAndroid Build Coastguard Worker 
185*ec779b8eSAndroid Build Coastguard Worker             if (outputThread != nullptr && !useHalSoundDoseInterface_l()) {
186*ec779b8eSAndroid Build Coastguard Worker                 outputThread->startMelComputation_l(
187*ec779b8eSAndroid Build Coastguard Worker                         mSoundDoseManager->getOrCreateProcessorForDevice(
188*ec779b8eSAndroid Build Coastguard Worker                                 device.first,
189*ec779b8eSAndroid Build Coastguard Worker                                 patch.streamHandle,
190*ec779b8eSAndroid Build Coastguard Worker                                 outputThread->sampleRate(),
191*ec779b8eSAndroid Build Coastguard Worker                                 outputThread->channelCount(),
192*ec779b8eSAndroid Build Coastguard Worker                                 outputThread->format()));
193*ec779b8eSAndroid Build Coastguard Worker             }
194*ec779b8eSAndroid Build Coastguard Worker         }
195*ec779b8eSAndroid Build Coastguard Worker     }
196*ec779b8eSAndroid Build Coastguard Worker }
197*ec779b8eSAndroid Build Coastguard Worker 
startMelComputationForDeviceId(audio_port_handle_t deviceId)198*ec779b8eSAndroid Build Coastguard Worker void MelReporter::startMelComputationForDeviceId(audio_port_handle_t deviceId) {
199*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s(%d)", __func__, deviceId);
200*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());
201*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
202*ec779b8eSAndroid Build Coastguard Worker 
203*ec779b8eSAndroid Build Coastguard Worker     for (auto& activeMelPatch : mActiveMelPatches) {
204*ec779b8eSAndroid Build Coastguard Worker         bool csdActive = false;
205*ec779b8eSAndroid Build Coastguard Worker         for (auto& device: activeMelPatch.second.deviceStates) {
206*ec779b8eSAndroid Build Coastguard Worker             if (device.first == deviceId && !device.second) {
207*ec779b8eSAndroid Build Coastguard Worker                 device.second = true;
208*ec779b8eSAndroid Build Coastguard Worker             }
209*ec779b8eSAndroid Build Coastguard Worker             csdActive |= device.second;
210*ec779b8eSAndroid Build Coastguard Worker         }
211*ec779b8eSAndroid Build Coastguard Worker         if (csdActive && !activeMelPatch.second.csdActive) {
212*ec779b8eSAndroid Build Coastguard Worker             activeMelPatch.second.csdActive = csdActive;
213*ec779b8eSAndroid Build Coastguard Worker             startMelComputationForActivePatch_l(activeMelPatch.second);
214*ec779b8eSAndroid Build Coastguard Worker         }
215*ec779b8eSAndroid Build Coastguard Worker     }
216*ec779b8eSAndroid Build Coastguard Worker }
217*ec779b8eSAndroid Build Coastguard Worker 
onReleaseAudioPatch(audio_patch_handle_t handle)218*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) {
219*ec779b8eSAndroid Build Coastguard Worker     if (!mSoundDoseManager->isCsdEnabled()) {
220*ec779b8eSAndroid Build Coastguard Worker         ALOGV("%s csd is disabled", __func__);
221*ec779b8eSAndroid Build Coastguard Worker         return;
222*ec779b8eSAndroid Build Coastguard Worker     }
223*ec779b8eSAndroid Build Coastguard Worker 
224*ec779b8eSAndroid Build Coastguard Worker     ActiveMelPatch melPatch;
225*ec779b8eSAndroid Build Coastguard Worker     {
226*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _l(mutex());
227*ec779b8eSAndroid Build Coastguard Worker 
228*ec779b8eSAndroid Build Coastguard Worker         auto patchIt = mActiveMelPatches.find(handle);
229*ec779b8eSAndroid Build Coastguard Worker         if (patchIt == mActiveMelPatches.end()) {
230*ec779b8eSAndroid Build Coastguard Worker             ALOGV("%s patch handle %d does not contain any mix sources with active MEL calculation",
231*ec779b8eSAndroid Build Coastguard Worker                     __func__, handle);
232*ec779b8eSAndroid Build Coastguard Worker             return;
233*ec779b8eSAndroid Build Coastguard Worker         }
234*ec779b8eSAndroid Build Coastguard Worker 
235*ec779b8eSAndroid Build Coastguard Worker         melPatch = patchIt->second;
236*ec779b8eSAndroid Build Coastguard Worker         mActiveMelPatches.erase(patchIt);
237*ec779b8eSAndroid Build Coastguard Worker     }
238*ec779b8eSAndroid Build Coastguard Worker 
239*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex());  // AudioFlinger_Mutex
240*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
241*ec779b8eSAndroid Build Coastguard Worker     if (melPatch.csdActive) {
242*ec779b8eSAndroid Build Coastguard Worker         // only need to stop if patch was active
243*ec779b8eSAndroid Build Coastguard Worker         melPatch.csdActive = false;
244*ec779b8eSAndroid Build Coastguard Worker         stopMelComputationForPatch_l(melPatch);
245*ec779b8eSAndroid Build Coastguard Worker     }
246*ec779b8eSAndroid Build Coastguard Worker }
247*ec779b8eSAndroid Build Coastguard Worker 
onUpdateAudioPatch(audio_patch_handle_t oldHandle,audio_patch_handle_t newHandle,const IAfPatchPanel::Patch & patch)248*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onUpdateAudioPatch(audio_patch_handle_t oldHandle,
249*ec779b8eSAndroid Build Coastguard Worker         audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
250*ec779b8eSAndroid Build Coastguard Worker     onReleaseAudioPatch(oldHandle);
251*ec779b8eSAndroid Build Coastguard Worker     onCreateAudioPatch(newHandle, patch);
252*ec779b8eSAndroid Build Coastguard Worker }
253*ec779b8eSAndroid Build Coastguard Worker 
getSoundDoseInterface(const sp<media::ISoundDoseCallback> & callback)254*ec779b8eSAndroid Build Coastguard Worker sp<media::ISoundDose> MelReporter::getSoundDoseInterface(
255*ec779b8eSAndroid Build Coastguard Worker         const sp<media::ISoundDoseCallback>& callback) {
256*ec779b8eSAndroid Build Coastguard Worker     // no need to lock since getSoundDoseInterface is synchronized
257*ec779b8eSAndroid Build Coastguard Worker     return mSoundDoseManager->getSoundDoseInterface(callback);
258*ec779b8eSAndroid Build Coastguard Worker }
259*ec779b8eSAndroid Build Coastguard Worker 
stopInternalMelComputation()260*ec779b8eSAndroid Build Coastguard Worker void MelReporter::stopInternalMelComputation() {
261*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s", __func__);
262*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
263*ec779b8eSAndroid Build Coastguard Worker     if (mUseHalSoundDoseInterface) {
264*ec779b8eSAndroid Build Coastguard Worker         return;
265*ec779b8eSAndroid Build Coastguard Worker     }
266*ec779b8eSAndroid Build Coastguard Worker     mActiveMelPatches.clear();
267*ec779b8eSAndroid Build Coastguard Worker     mUseHalSoundDoseInterface = true;
268*ec779b8eSAndroid Build Coastguard Worker }
269*ec779b8eSAndroid Build Coastguard Worker 
stopMelComputationForPatch_l(const ActiveMelPatch & patch)270*ec779b8eSAndroid Build Coastguard Worker void MelReporter::stopMelComputationForPatch_l(const ActiveMelPatch& patch)
271*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS  // access of AudioFlinger::checkOutputThread_l
272*ec779b8eSAndroid Build Coastguard Worker {
273*ec779b8eSAndroid Build Coastguard Worker     auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
274*ec779b8eSAndroid Build Coastguard Worker 
275*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle);
276*ec779b8eSAndroid Build Coastguard Worker     for (const auto& device : patch.deviceStates) {
277*ec779b8eSAndroid Build Coastguard Worker         if (mActiveDevices[device.first] > 0) {
278*ec779b8eSAndroid Build Coastguard Worker             --mActiveDevices[device.first];
279*ec779b8eSAndroid Build Coastguard Worker             if (mActiveDevices[device.first] == 0) {
280*ec779b8eSAndroid Build Coastguard Worker                 // no stream is using deviceId anymore
281*ec779b8eSAndroid Build Coastguard Worker                 ALOGI("%s removing device %d from active CSD devices", __func__, device.first);
282*ec779b8eSAndroid Build Coastguard Worker                 mSoundDoseManager->clearMapDeviceIdEntries(device.first);
283*ec779b8eSAndroid Build Coastguard Worker             }
284*ec779b8eSAndroid Build Coastguard Worker         }
285*ec779b8eSAndroid Build Coastguard Worker     }
286*ec779b8eSAndroid Build Coastguard Worker 
287*ec779b8eSAndroid Build Coastguard Worker     mSoundDoseManager->removeStreamProcessor(patch.streamHandle);
288*ec779b8eSAndroid Build Coastguard Worker     if (outputThread != nullptr && !useHalSoundDoseInterface_l()) {
289*ec779b8eSAndroid Build Coastguard Worker         outputThread->stopMelComputation_l();
290*ec779b8eSAndroid Build Coastguard Worker     }
291*ec779b8eSAndroid Build Coastguard Worker }
292*ec779b8eSAndroid Build Coastguard Worker 
stopMelComputationForDeviceId(audio_port_handle_t deviceId)293*ec779b8eSAndroid Build Coastguard Worker void MelReporter::stopMelComputationForDeviceId(audio_port_handle_t deviceId) {
294*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s(%d)", __func__, deviceId);
295*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());
296*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
297*ec779b8eSAndroid Build Coastguard Worker 
298*ec779b8eSAndroid Build Coastguard Worker     for (auto& activeMelPatch : mActiveMelPatches) {
299*ec779b8eSAndroid Build Coastguard Worker         bool csdActive = false;
300*ec779b8eSAndroid Build Coastguard Worker         for (auto& device: activeMelPatch.second.deviceStates) {
301*ec779b8eSAndroid Build Coastguard Worker             if (device.first == deviceId && device.second) {
302*ec779b8eSAndroid Build Coastguard Worker                 device.second = false;
303*ec779b8eSAndroid Build Coastguard Worker             }
304*ec779b8eSAndroid Build Coastguard Worker             csdActive |= device.second;
305*ec779b8eSAndroid Build Coastguard Worker         }
306*ec779b8eSAndroid Build Coastguard Worker 
307*ec779b8eSAndroid Build Coastguard Worker         if (!csdActive && activeMelPatch.second.csdActive) {
308*ec779b8eSAndroid Build Coastguard Worker             activeMelPatch.second.csdActive = csdActive;
309*ec779b8eSAndroid Build Coastguard Worker             stopMelComputationForPatch_l(activeMelPatch.second);
310*ec779b8eSAndroid Build Coastguard Worker         }
311*ec779b8eSAndroid Build Coastguard Worker     }
312*ec779b8eSAndroid Build Coastguard Worker 
313*ec779b8eSAndroid Build Coastguard Worker }
314*ec779b8eSAndroid Build Coastguard Worker 
applyAllAudioPatches()315*ec779b8eSAndroid Build Coastguard Worker void MelReporter::applyAllAudioPatches() {
316*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s", __func__);
317*ec779b8eSAndroid Build Coastguard Worker 
318*ec779b8eSAndroid Build Coastguard Worker     std::vector<IAfPatchPanel::Patch> patchesCopy;
319*ec779b8eSAndroid Build Coastguard Worker     {
320*ec779b8eSAndroid Build Coastguard Worker         audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());
321*ec779b8eSAndroid Build Coastguard Worker         for (const auto& patch : mAfPatchPanel->patches_l()) {
322*ec779b8eSAndroid Build Coastguard Worker             patchesCopy.emplace_back(patch.second);
323*ec779b8eSAndroid Build Coastguard Worker         }
324*ec779b8eSAndroid Build Coastguard Worker     }
325*ec779b8eSAndroid Build Coastguard Worker 
326*ec779b8eSAndroid Build Coastguard Worker     for (const auto& patch : patchesCopy) {
327*ec779b8eSAndroid Build Coastguard Worker         onCreateAudioPatch(patch.mHalHandle, patch);
328*ec779b8eSAndroid Build Coastguard Worker     }
329*ec779b8eSAndroid Build Coastguard Worker }
330*ec779b8eSAndroid Build Coastguard Worker 
activePatchStreamHandle_l(audio_io_handle_t streamHandle)331*ec779b8eSAndroid Build Coastguard Worker std::optional<audio_patch_handle_t> MelReporter::activePatchStreamHandle_l(
332*ec779b8eSAndroid Build Coastguard Worker         audio_io_handle_t streamHandle) {
333*ec779b8eSAndroid Build Coastguard Worker     for(const auto& patchIt : mActiveMelPatches) {
334*ec779b8eSAndroid Build Coastguard Worker         if (patchIt.second.streamHandle == streamHandle) {
335*ec779b8eSAndroid Build Coastguard Worker             return patchIt.first;
336*ec779b8eSAndroid Build Coastguard Worker         }
337*ec779b8eSAndroid Build Coastguard Worker     }
338*ec779b8eSAndroid Build Coastguard Worker     return std::nullopt;
339*ec779b8eSAndroid Build Coastguard Worker }
340*ec779b8eSAndroid Build Coastguard Worker 
useHalSoundDoseInterface_l()341*ec779b8eSAndroid Build Coastguard Worker bool MelReporter::useHalSoundDoseInterface_l() {
342*ec779b8eSAndroid Build Coastguard Worker     return !mSoundDoseManager->isFrameworkMelForced() & mUseHalSoundDoseInterface;
343*ec779b8eSAndroid Build Coastguard Worker }
344*ec779b8eSAndroid Build Coastguard Worker 
dump()345*ec779b8eSAndroid Build Coastguard Worker std::string MelReporter::dump() {
346*ec779b8eSAndroid Build Coastguard Worker     audio_utils::lock_guard _l(mutex());
347*ec779b8eSAndroid Build Coastguard Worker     std::string output("\nSound Dose:\n");
348*ec779b8eSAndroid Build Coastguard Worker     output.append(mSoundDoseManager->dump());
349*ec779b8eSAndroid Build Coastguard Worker     return output;
350*ec779b8eSAndroid Build Coastguard Worker }
351*ec779b8eSAndroid Build Coastguard Worker 
352*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
353