audio policy: check audio attributes with use case validator
Add calls to use case validator when playback and capture starts
to fix incomplete or default usages in audio attributes.
Bug: 257922898
Test: libaudiousecasevalidation-test
Change-Id: I5c22c34564a101eb9773988919cff6ded370485e
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index a5fa78b..8e0315b 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -137,7 +137,7 @@
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
- const AttributionSourceState& attributionSouce,
+ const AttributionSourceState& attributionSource,
audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
@@ -160,7 +160,7 @@
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
- const AttributionSourceState& attributionSouce,
+ const AttributionSourceState& attributionSource,
audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t *selectedDeviceId,
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 4c19d40..10403fa 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -36,6 +36,7 @@
"libaudiohal",
"libaudiopolicy",
"libaudiopolicymanagerdefault",
+ "libaudiousecasevalidation",
"libaudioutils",
"libbinder",
"libcutils",
@@ -85,6 +86,7 @@
export_shared_lib_headers: [
"libactivitymanager_aidl",
+ "libaudiousecasevalidation",
"libheadtracking",
"libheadtracking-binding",
"libsensorprivacy",
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index c766a15..5d420b5 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -69,6 +69,12 @@
*halConfig = VALUE_OR_RETURN_STATUS(
aidl2legacy_AudioConfig_audio_config_t(response.config, false /*isInput*/));
*latencyMs = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(response.latencyMs));
+
+ audio_config_base_t config = {.sample_rate = halConfig->sample_rate,
+ .channel_mask = halConfig->channel_mask,
+ .format = halConfig->format,
+ };
+ mAudioPolicyService->registerOutput(*output, config, flags);
}
return status;
}
@@ -91,7 +97,7 @@
if (af == 0) {
return PERMISSION_DENIED;
}
-
+ mAudioPolicyService->unregisterOutput(output);
return af->closeOutput(output);
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 4eb5336..63a9bea 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -417,6 +417,9 @@
}
if (result == NO_ERROR) {
+ attr = VALUE_OR_RETURN_BINDER_STATUS(
+ mUsecaseValidator->verifyAudioAttributes(output, attributionSource, attr));
+
sp<AudioPlaybackClient> client =
new AudioPlaybackClient(attr, output, attributionSource, session,
portId, selectedDeviceId, stream, isSpatialized);
@@ -435,6 +438,8 @@
legacy2aidl_audio_io_handle_t_int32_t));
_aidl_return->isSpatialized = isSpatialized;
_aidl_return->isBitPerfect = isBitPerfect;
+ _aidl_return->attr = VALUE_OR_RETURN_BINDER_STATUS(
+ legacy2aidl_audio_attributes_t_AudioAttributesInternal(attr));
} else {
_aidl_return->configBase.format = VALUE_OR_RETURN_BINDER_STATUS(
legacy2aidl_audio_format_t_AudioFormatDescription(config.format));
@@ -486,6 +491,10 @@
AutoCallerClear acc;
status_t status = mAudioPolicyManager->startOutput(portId);
if (status == NO_ERROR) {
+ //TODO b/257922898: decide if/how we need to handle attributes update when playback starts
+ // or during playback
+ (void)mUsecaseValidator->startClient(client->io, client->portId, client->attributionSource,
+ client->attributes, nullptr /* callback */);
client->active = true;
onUpdateActiveSpatializerTracks_l();
}
@@ -526,6 +535,7 @@
if (status == NO_ERROR) {
client->active = false;
onUpdateActiveSpatializerTracks_l();
+ mUsecaseValidator->stopClient(client->io, client->portId);
}
return status;
}
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 48997db..2be5121 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -205,7 +205,8 @@
mPhoneState(AUDIO_MODE_INVALID),
mCaptureStateNotifier(false),
mCreateAudioPolicyManager(createAudioPolicyManager),
- mDestroyAudioPolicyManager(destroyAudioPolicyManager) {
+ mDestroyAudioPolicyManager(destroyAudioPolicyManager),
+ mUsecaseValidator(media::createUsecaseValidator()) {
setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
}
@@ -1537,6 +1538,16 @@
" help print this message\n");
}
+status_t AudioPolicyService::registerOutput(audio_io_handle_t output,
+ const audio_config_base_t& config,
+ const audio_output_flags_t flags) {
+ return mUsecaseValidator->registerStream(output, config, flags);
+}
+
+status_t AudioPolicyService::unregisterOutput(audio_io_handle_t output) {
+ return mUsecaseValidator->unregisterStream(output);
+}
+
// ----------- AudioPolicyService::UidPolicy implementation ----------
void AudioPolicyService::UidPolicy::registerSelf() {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 58af46d..5aa828e 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -36,6 +36,7 @@
#include <media/ToneGenerator.h>
#include <media/AudioEffect.h>
#include <media/AudioPolicy.h>
+#include <media/UsecaseValidator.h>
#include <mediautils/ServiceUtilities.h>
#include "AudioPolicyEffects.h"
#include "CaptureStateNotifier.h"
@@ -431,6 +432,11 @@
*/
static bool isAppOpSource(audio_source_t source);
+ status_t registerOutput(audio_io_handle_t output,
+ const audio_config_base_t& config,
+ const audio_output_flags_t flags);
+ status_t unregisterOutput(audio_io_handle_t output);
+
// If recording we need to make sure the UID is allowed to do that. If the UID is idle
// then it cannot record and gets buffers with zeros - silence. As soon as the UID
// transitions to an active state we will start reporting buffers with data. This approach
@@ -903,7 +909,7 @@
const audio_attributes_t attributes; // source, flags ...
const audio_io_handle_t io; // audio HAL stream IO handle
- const AttributionSourceState& attributionSource; //client attributionsource
+ const AttributionSourceState attributionSource; //client attributionsource
const audio_session_t session; // audio session ID
const audio_port_handle_t portId;
const audio_port_handle_t deviceId; // selected input device port ID
@@ -1082,6 +1088,7 @@
void *mLibraryHandle = nullptr;
CreateAudioPolicyManagerInstance mCreateAudioPolicyManager;
DestroyAudioPolicyManagerInstance mDestroyAudioPolicyManager;
+ std::unique_ptr<media::UsecaseValidator> mUsecaseValidator;
};
} // namespace android