CSD: forward the native MEL exposure to AudioService
Added new aidl interface for the communication between the
SoundDoseManager and the SoundDoseHelper. Currently only the momentary
exposure warning is reported.
Test: manual
Bug: 257238734
Change-Id: I61560f81fedd31c30c39d676b7adf0ce087b495c
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 8850db1..57a4133 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -451,6 +451,8 @@
"aidl/android/media/IAudioRecord.aidl",
"aidl/android/media/IAudioTrack.aidl",
"aidl/android/media/IAudioTrackCallback.aidl",
+
+ "aidl/android/media/ISoundDoseCallback.aidl",
],
imports: [
"android.media.audio.common.types-V2",
@@ -542,3 +544,19 @@
},
},
}
+
+aidl_interface {
+ name: "sounddose-aidl",
+ unstable: true,
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/android/media/ISoundDoseCallback.aidl",
+ ],
+
+ double_loadable: true,
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ },
+ },
+}
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index af00ab1..fa9239f 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -2374,6 +2374,15 @@
return OK;
}
+status_t AudioSystem::registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ return PERMISSION_DENIED;
+ }
+
+ return af->registerSoundDoseCallback(callback);
+}
+
status_t AudioSystem::getDirectPlaybackSupport(const audio_attributes_t *attr,
const audio_config_t *config,
audio_direct_mode_t* directMode) {
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 6ad97d1..97b61a5 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -837,6 +837,11 @@
return NO_ERROR;
}
+status_t AudioFlingerClientAdapter::registerSoundDoseCallback(
+ const sp<media::ISoundDoseCallback> &callback) {
+ return statusTFromBinderStatus(mDelegate->registerSoundDoseCallback(callback));
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
AudioFlingerServerAdapter::AudioFlingerServerAdapter(
@@ -1355,4 +1360,10 @@
return Status::ok();
}
+Status AudioFlingerServerAdapter::registerSoundDoseCallback(
+ const sp<media::ISoundDoseCallback>& callback)
+{
+ return Status::fromStatusT(mDelegate->registerSoundDoseCallback(callback));
+}
+
} // namespace android
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 9b8a843..133e363 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -35,6 +35,7 @@
import android.media.IAudioFlingerClient;
import android.media.IAudioRecord;
import android.media.IAudioTrack;
+import android.media.ISoundDoseCallback;
import android.media.LatencyMode;
import android.media.MicrophoneInfoData;
import android.media.RenderPosition;
@@ -246,6 +247,9 @@
*/
LatencyMode[] getSupportedLatencyModes(int output);
+ /** Registers the sound dose callback. */
+ oneway void registerSoundDoseCallback(ISoundDoseCallback callback);
+
// When adding a new method, please review and update
// IAudioFlinger.h AudioFlingerServerAdapter::Delegate::TransactionCode
// AudioFlinger.cpp AudioFlinger::onTransactWrapper()
diff --git a/media/libaudioclient/aidl/android/media/ISoundDoseCallback.aidl b/media/libaudioclient/aidl/android/media/ISoundDoseCallback.aidl
new file mode 100644
index 0000000..3edf681
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/ISoundDoseCallback.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+/**
+ * Interface used to push the sound dose related information from the audio
+ * server to the AudioService#SoundDoseHelper.
+ */
+interface ISoundDoseCallback {
+ /** Called whenever the momentary exposure exceeds the RS2 value. */
+ oneway void onMomentaryExposure(float currentMel, int deviceId);
+}
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 6e6b9c8..a5feb3d 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -28,6 +28,7 @@
#include <android/media/BnAudioPolicyServiceClient.h>
#include <android/media/EffectDescriptor.h>
#include <android/media/INativeSpatializerCallback.h>
+#include <android/media/ISoundDoseCallback.h>
#include <android/media/ISpatializer.h>
#include <android/media/RecordClientInfo.h>
#include <android/media/audio/common/AudioConfigBase.h>
@@ -585,6 +586,9 @@
const AudioDeviceTypeAddrVector &devices,
bool *canBeSpatialized);
+ /** Registers the sound dose callback with the audio server. */
+ static status_t registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback);
+
/**
* Query how the direct playback is currently supported on the device.
* @param attr audio attributes describing the playback use case
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index c891ae6..c883e18 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -55,6 +55,7 @@
#include "android/media/IAudioTrackCallback.h"
#include "android/media/IEffect.h"
#include "android/media/IEffectClient.h"
+#include "android/media/ISoundDoseCallback.h"
#include "android/media/OpenInputRequest.h"
#include "android/media/OpenInputResponse.h"
#include "android/media/OpenOutputRequest.h"
@@ -367,6 +368,7 @@
virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes) = 0;
+ virtual status_t registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback) = 0;
};
/**
@@ -473,6 +475,7 @@
audio_latency_mode_t mode) override;
status_t getSupportedLatencyModes(
audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) override;
+ status_t registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback) override;
private:
const sp<media::IAudioFlingerService> mDelegate;
@@ -564,6 +567,7 @@
SET_DEVICE_CONNECTED_STATE = media::BnAudioFlingerService::TRANSACTION_setDeviceConnectedState,
SET_REQUESTED_LATENCY_MODE = media::BnAudioFlingerService::TRANSACTION_setRequestedLatencyMode,
GET_SUPPORTED_LATENCY_MODES = media::BnAudioFlingerService::TRANSACTION_getSupportedLatencyModes,
+ REGISTER_SOUND_DOSE_CALLBACK = media::BnAudioFlingerService::TRANSACTION_registerSoundDoseCallback,
};
protected:
@@ -688,6 +692,7 @@
Status setRequestedLatencyMode(int output, media::LatencyMode mode) override;
Status getSupportedLatencyModes(int output,
std::vector<media::LatencyMode>* _aidl_return) override;
+ Status registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback) override;
private:
const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
};
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d5100fe..0719838 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -229,7 +229,7 @@
BINDER_METHOD_ENTRY(setDeviceConnectedState) \
BINDER_METHOD_ENTRY(setRequestedLatencyMode) \
BINDER_METHOD_ENTRY(getSupportedLatencyModes) \
-
+BINDER_METHOD_ENTRY(registerSoundDoseCallback) \
// singleton for Binder Method Statistics for IAudioFlinger
static auto& getIAudioFlingerStatistics() {
@@ -1657,6 +1657,11 @@
return thread->getSupportedLatencyModes(modes);
}
+status_t AudioFlinger::registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback) {
+ mMelReporter->registerSoundDoseCallback(callback);
+ return NO_ERROR;
+}
+
status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
{
// check calling permissions
@@ -4613,6 +4618,7 @@
case TransactionCode::SET_MASTER_VOLUME:
case TransactionCode::SET_MASTER_MUTE:
case TransactionCode::MASTER_MUTE:
+ case TransactionCode::REGISTER_SOUND_DOSE_CALLBACK:
case TransactionCode::SET_MODE:
case TransactionCode::SET_MIC_MUTE:
case TransactionCode::SET_LOW_RAM_DEVICE:
@@ -4624,7 +4630,7 @@
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid());
- // return status only for non void methods
+ // return status only for non-void methods
switch (code) {
case TransactionCode::SYSTEM_READY:
break;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index d2a033e..a2cde70 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -123,6 +123,7 @@
class EffectsFactoryHalInterface;
class FastMixer;
class IAudioManager;
+class ISoundDoseCallback;
class PassthruBufferProvider;
class RecordBufferConverter;
class ServerProxy;
@@ -305,6 +306,8 @@
virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes);
+ virtual status_t registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback);
+
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
const std::function<status_t()>& delegate) override;
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index 6fc756b..279f30d 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -20,6 +20,7 @@
#include "AudioFlinger.h"
+#include <android/media/ISoundDoseCallback.h>
#include <audio_utils/power.h>
#include <utils/Log.h>
@@ -107,6 +108,12 @@
}
}
+void AudioFlinger::MelReporter::registerSoundDoseCallback(
+ const sp<media::ISoundDoseCallback>& callback) {
+ // no need to lock since registerSoundDoseCallback is synchronized
+ mSoundDoseManager.registerSoundDoseCallback(callback);
+}
+
std::string AudioFlinger::MelReporter::dump() {
std::lock_guard _l(mLock);
std::string output("\nSound Dose:\n");
diff --git a/services/audioflinger/MelReporter.h b/services/audioflinger/MelReporter.h
index 8a78f6e..3625a86 100644
--- a/services/audioflinger/MelReporter.h
+++ b/services/audioflinger/MelReporter.h
@@ -44,6 +44,8 @@
// For now only support internal MelReporting
[[nodiscard]] bool isHalReportingEnabled() const { return false; }
+ void registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback);
+
std::string dump();
// PatchCommandListener methods
diff --git a/services/audioflinger/sounddose/Android.bp b/services/audioflinger/sounddose/Android.bp
index 5c72fba..6149472 100644
--- a/services/audioflinger/sounddose/Android.bp
+++ b/services/audioflinger/sounddose/Android.bp
@@ -17,6 +17,7 @@
],
shared_libs: [
+ "audioflinger-aidl-cpp",
"libaudioutils",
"libbase",
"liblog",
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index 0a69c52..86fb3a4 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -123,6 +123,23 @@
__func__,
deviceId,
currentMel);
+
+ sp<media::ISoundDoseCallback> soundDoseCallback;
+ {
+ std::lock_guard _l(mLock);
+ soundDoseCallback = mSoundDoseCallback;
+ }
+
+ if (soundDoseCallback != nullptr) {
+ mSoundDoseCallback->onMomentaryExposure(currentMel, deviceId);
+ }
+}
+
+void SoundDoseManager::registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback) {
+ ALOGV("%s: Register ISoundDoseCallback", __func__);
+
+ std::lock_guard _l(mLock);
+ mSoundDoseCallback = callback;
}
std::string SoundDoseManager::dump() const
diff --git a/services/audioflinger/sounddose/SoundDoseManager.h b/services/audioflinger/sounddose/SoundDoseManager.h
index 5934d2e..754b569 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.h
+++ b/services/audioflinger/sounddose/SoundDoseManager.h
@@ -17,6 +17,7 @@
#pragma once
+#include <android/media/ISoundDoseCallback.h>
#include <audio_utils/MelProcessor.h>
#include <audio_utils/MelAggregator.h>
#include <mutex>
@@ -71,6 +72,9 @@
std::string dump() const;
+ /** \brief Registers the interface for passing callbacks to the AudioService. */
+ void registerSoundDoseCallback(const sp<media::ISoundDoseCallback>& callback);
+
// used for testing
size_t getCachedMelRecordsSize() const;
@@ -91,6 +95,8 @@
wp<audio_utils::MelProcessor>> mActiveProcessors GUARDED_BY(mLock);
float mRs2Value GUARDED_BY(mLock);
+
+ sp<media::ISoundDoseCallback> mSoundDoseCallback GUARDED_BY(mLock);
};
} // namespace android
diff --git a/services/audioflinger/sounddose/tests/Android.bp b/services/audioflinger/sounddose/tests/Android.bp
index d1779c2..a886663 100644
--- a/services/audioflinger/sounddose/tests/Android.bp
+++ b/services/audioflinger/sounddose/tests/Android.bp
@@ -15,6 +15,7 @@
],
shared_libs: [
+ "audioflinger-aidl-cpp",
"libaudioutils",
"libbase",
"liblog",