Add support for USAGE_VOICE_COMMUNICATION playback capture
Allow audio playback capture for the USAGE_VOICE_COMMUNICATION usage
only for priveliged apps that are granted with the CAPTURE_VOICE_COMMUNICATION_OUTPUT
permission.
Test: atest android.media.cts.AudioPlaybackCaptureTest
Test: Manually
Bug: 124653474
Change-Id: Ib568ca590ea534837c396536f5e31cf60a5caf52
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index 06fc23c..4499845 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -168,4 +168,11 @@
&& (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
}
+bool AudioMix::hasMatchingRuleForUsage(std::function<bool (audio_usage_t)>const& func) const {
+ return std::any_of(mCriteria.begin(), mCriteria.end(), [func](auto& criterion) {
+ return criterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE
+ && func(criterion.mValue.mUsage);
+ });
+}
+
} // namespace android
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 0ab1c9d..1528464 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -18,6 +18,7 @@
#ifndef ANDROID_AUDIO_POLICY_H
#define ANDROID_AUDIO_POLICY_H
+#include <functional>
#include <binder/Parcel.h>
#include <media/AudioDeviceTypeAddr.h>
#include <system/audio.h>
@@ -101,6 +102,13 @@
/** returns true if this mix can be used for uid-device affinity routing */
bool isDeviceAffinityCompatible() const;
+ /**
+ * returns true if the mix has a capture rule for a usage that
+ * matches the given predicate
+ */
+ bool hasMatchingRuleForUsage(
+ std::function<bool (audio_usage_t)>const& func) const;
+
mutable Vector<AudioMixMatchCriterion> mCriteria;
uint32_t mMixType;
audio_config_t mFormat;
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 343ec05..87ea084 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -145,6 +145,15 @@
return ok;
}
+bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid) {
+ if (isAudioServerOrRootUid(uid)) return true;
+ static const String16 sCaptureVoiceCommOutput(
+ "android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
+ bool ok = PermissionCache::checkPermission(sCaptureVoiceCommOutput, pid, uid);
+ if (!ok) ALOGE("Request requires android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
+ return ok;
+}
+
bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
// CAPTURE_AUDIO_HOTWORD permission implies RECORD_AUDIO permission
bool ok = recordingAllowed(opPackageName, pid, uid);
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 4925cdb..212599a 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -83,6 +83,7 @@
void finishRecording(const String16& opPackageName, uid_t uid);
bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
bool captureMediaOutputAllowed(pid_t pid, uid_t uid);
+bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid);
bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
bool settingsAllowed();
bool modifyAudioRoutingAllowed();