Fix voice communication audio playback capture
This change fixes the CTS failure in AudioPlaybackCaptureTest caused
by ag/10111312 and ag/10111311.
It contains the following fixes/changes:
- Mix match for playback capture of USAGE_VOICE_COMMUNICATION now
also respects a new flag (AudioMix's mVoiceCommunicationCaptureAllowed)
which is set by AudioService only if the caller explicitly asked
to capture USAGE_VOICE_COMMUNICATION and have the
CAPTURE_VOICE_COMMUNICATION_OUTPUT.
- A permission check on the native side in case
mVoiceCommunicationCaptureAllowed is set.
- Code cleanup, mainly in AudioPolicy.h and AudioPolicy.cpp.
This change is accompanied by ag/10242955 on the Java side.
Bug: 148559127
Test: manual
Test: atest PlaybackCaptureTest (with the version prior to ag/10220852)
Test: atest com.google.android.gts.audio.AudioHostTest
Change-Id: I8ae6249f4da1de35e962c838d91f690eb906570e
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index bf1a34f..ed51389 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -224,6 +224,10 @@
hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
return MixMatchStatus::NO_MATCH;
}
+ if (attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION &&
+ !mix->mVoiceCommunicationCaptureAllowed) {
+ return MixMatchStatus::NO_MATCH;
+ }
if (!(attributes.usage == AUDIO_USAGE_UNKNOWN ||
attributes.usage == AUDIO_USAGE_MEDIA ||
attributes.usage == AUDIO_USAGE_GAME ||
diff --git a/services/audiopolicy/service/Android.mk b/services/audiopolicy/service/Android.mk
index d34dbe3..80f4eab 100644
--- a/services/audiopolicy/service/Android.mk
+++ b/services/audiopolicy/service/Android.mk
@@ -26,7 +26,6 @@
libaudioutils \
libaudiofoundation \
libhardware_legacy \
- libaudiopolicy \
libaudiopolicymanager \
libmedia_helper \
libmediametrics \
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 8bc2837..ba3d4ff 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1215,26 +1215,14 @@
return PERMISSION_DENIED;
}
- // Require CAPTURE_VOICE_COMMUNICATION_OUTPUT if one of the
- // mixes is a render|loopback mix that aim to capture audio played with
- // USAGE_VOICE_COMMUNICATION.
+ // If one of the mixes has needCaptureVoiceCommunicationOutput set to true, then we
+ // need to verify that the caller still has CAPTURE_VOICE_COMMUNICATION_OUTPUT
bool needCaptureVoiceCommunicationOutput =
std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
- return is_mix_loopback_render(mix.mRouteFlags) &&
- mix.hasMatchingRuleForUsage([] (auto usage) {
- return usage == AUDIO_USAGE_VOICE_COMMUNICATION;});
- });
+ return mix.mVoiceCommunicationCaptureAllowed; });
- // Require CAPTURE_MEDIA_OUTPUT if there is a mix for priveliged capture
- // which is trying to capture any usage which is not USAGE_VOICE_COMMUNICATION.
- // (If USAGE_VOICE_COMMUNICATION should be captured, then CAPTURE_VOICE_COMMUNICATION_OUTPUT
- // is required, even if it is not privileged capture).
bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
- return mix.mAllowPrivilegedPlaybackCapture &&
- mix.hasMatchingRuleForUsage([] (auto usage) {
- return usage != AUDIO_USAGE_VOICE_COMMUNICATION;
- });
- });
+ return mix.mAllowPrivilegedPlaybackCapture; });
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
const pid_t callingPid = IPCThreadState::self()->getCallingPid();