Loading core/jni/android_media_AudioSystem.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1946,7 +1946,7 @@ static jint convertAudioMixToNative(JNIEnv *env, jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule); jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria); nAudioMix->mAllowPrivilegedPlaybackCapture = nAudioMix->mAllowPrivilegedMediaPlaybackCapture = env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture); nAudioMix->mVoiceCommunicationCaptureAllowed = env->GetBooleanField(jRule, gAudioMixingRuleFields.mVoiceCommunicationCaptureAllowed); Loading media/java/android/media/audiopolicy/AudioMix.java +3 −3 Original line number Diff line number Diff line Loading @@ -218,7 +218,7 @@ public class AudioMix { /** @return an error string if the format would not allow Privileged playbackCapture * null otherwise * @hide */ public static String canBeUsedForPrivilegedCapture(AudioFormat format) { public static String canBeUsedForPrivilegedMediaCapture(AudioFormat format) { int sampleRate = format.getSampleRate(); if (sampleRate > PRIVILEDGED_CAPTURE_MAX_SAMPLE_RATE || sampleRate <= 0) { return "Privileged audio capture sample rate " + sampleRate Loading Loading @@ -448,8 +448,8 @@ public class AudioMix { } } } if (mRule.allowPrivilegedPlaybackCapture()) { String error = AudioMix.canBeUsedForPrivilegedCapture(mFormat); if (mRule.allowPrivilegedMediaPlaybackCapture()) { String error = AudioMix.canBeUsedForPrivilegedMediaCapture(mFormat); if (error != null) { throw new IllegalArgumentException(error); } Loading media/java/android/media/audiopolicy/AudioMixingRule.java +10 −6 Original line number Diff line number Diff line Loading @@ -46,11 +46,11 @@ import java.util.Objects; public class AudioMixingRule { private AudioMixingRule(int mixType, ArrayList<AudioMixMatchCriterion> criteria, boolean allowPrivilegedPlaybackCapture, boolean allowPrivilegedMediaPlaybackCapture, boolean voiceCommunicationCaptureAllowed) { mCriteria = criteria; mTargetMixType = mixType; mAllowPrivilegedPlaybackCapture = allowPrivilegedPlaybackCapture; mAllowPrivilegedPlaybackCapture = allowPrivilegedMediaPlaybackCapture; mVoiceCommunicationCaptureAllowed = voiceCommunicationCaptureAllowed; } Loading Loading @@ -204,13 +204,17 @@ public class AudioMixingRule { private final ArrayList<AudioMixMatchCriterion> mCriteria; /** @hide */ public ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; } /** Indicates that this rule is intended to capture media or game playback by a system component * with permission CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT. */ //TODO b/177061175: rename to mAllowPrivilegedMediaPlaybackCapture @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mAllowPrivilegedPlaybackCapture = false; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mVoiceCommunicationCaptureAllowed = false; /** @hide */ public boolean allowPrivilegedPlaybackCapture() { public boolean allowPrivilegedMediaPlaybackCapture() { return mAllowPrivilegedPlaybackCapture; } Loading Loading @@ -311,7 +315,7 @@ public class AudioMixingRule { public static class Builder { private ArrayList<AudioMixMatchCriterion> mCriteria; private int mTargetMixType = AudioMix.MIX_TYPE_INVALID; private boolean mAllowPrivilegedPlaybackCapture = false; private boolean mAllowPrivilegedMediaPlaybackCapture = false; // This value should be set internally according to a permission check private boolean mVoiceCommunicationCaptureAllowed = false; Loading Loading @@ -434,7 +438,7 @@ public class AudioMixingRule { * @return the same Builder instance. */ public @NonNull Builder allowPrivilegedPlaybackCapture(boolean allow) { mAllowPrivilegedPlaybackCapture = allow; mAllowPrivilegedMediaPlaybackCapture = allow; return this; } Loading Loading @@ -639,7 +643,7 @@ public class AudioMixingRule { */ public AudioMixingRule build() { return new AudioMixingRule(mTargetMixType, mCriteria, mAllowPrivilegedPlaybackCapture, mVoiceCommunicationCaptureAllowed); mAllowPrivilegedMediaPlaybackCapture, mVoiceCommunicationCaptureAllowed); } } } media/java/android/media/audiopolicy/AudioPolicyConfig.java +2 −2 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ public class AudioPolicyConfig implements Parcelable { dest.writeInt(mix.getFormat().getEncoding()); dest.writeInt(mix.getFormat().getChannelMask()); // write opt-out respect dest.writeBoolean(mix.getRule().allowPrivilegedPlaybackCapture()); dest.writeBoolean(mix.getRule().allowPrivilegedMediaPlaybackCapture()); // write voice communication capture allowed flag dest.writeBoolean(mix.getRule().voiceCommunicationCaptureAllowed()); // write mix rules Loading Loading @@ -172,7 +172,7 @@ public class AudioPolicyConfig implements Parcelable { textDump += " channels=0x"; textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() + "\n"; textDump += " ignore playback capture opt out=" + mix.getRule().allowPrivilegedPlaybackCapture() + "\n"; + mix.getRule().allowPrivilegedMediaPlaybackCapture() + "\n"; textDump += " allow voice communication capture=" + mix.getRule().voiceCommunicationCaptureAllowed() + "\n"; // write mix rules Loading services/core/java/com/android/server/audio/AudioService.java +20 −19 Original line number Diff line number Diff line Loading @@ -8454,21 +8454,23 @@ public class AudioService extends IAudioService.Stub } for (AudioMix mix : policyConfig.getMixes()) { // If mix is requesting privileged capture if (mix.getRule().allowPrivilegedPlaybackCapture()) { // then it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission requireCaptureAudioOrMediaOutputPerm |= true; // and its format must be low quality enough String error = mix.canBeUsedForPrivilegedCapture(mix.getFormat()); if (error != null) { Log.e(TAG, error); if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { // then its format must be low quality enough String privilegedMediaCaptureError = mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); if (privilegedMediaCaptureError != null) { Log.e(TAG, privilegedMediaCaptureError); return false; } // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission requireCaptureAudioOrMediaOutputPerm |= true; // If mix is trying to excplicitly capture USAGE_VOICE_COMMUNICATION } // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION if (mix.containsMatchAttributeRuleForUsage( AudioAttributes.USAGE_VOICE_COMMUNICATION)) { // then it must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission AudioAttributes.USAGE_VOICE_COMMUNICATION) && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced // in AudioPolicyMix if (voiceCommunicationCaptureMixes == null) { Loading @@ -8476,7 +8478,6 @@ public class AudioService extends IAudioService.Stub } voiceCommunicationCaptureMixes.add(mix); } } // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough // otherwise MODIFY_AUDIO_ROUTING permission is required Loading @@ -8498,7 +8499,7 @@ public class AudioService extends IAudioService.Stub if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { if (!callerHasPermission( android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { Log.e(TAG, "Privileged audio capture for voice communication requires " Log.e(TAG, "Audio capture for voice communication requires " + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); return false; } Loading Loading
core/jni/android_media_AudioSystem.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1946,7 +1946,7 @@ static jint convertAudioMixToNative(JNIEnv *env, jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule); jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria); nAudioMix->mAllowPrivilegedPlaybackCapture = nAudioMix->mAllowPrivilegedMediaPlaybackCapture = env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture); nAudioMix->mVoiceCommunicationCaptureAllowed = env->GetBooleanField(jRule, gAudioMixingRuleFields.mVoiceCommunicationCaptureAllowed); Loading
media/java/android/media/audiopolicy/AudioMix.java +3 −3 Original line number Diff line number Diff line Loading @@ -218,7 +218,7 @@ public class AudioMix { /** @return an error string if the format would not allow Privileged playbackCapture * null otherwise * @hide */ public static String canBeUsedForPrivilegedCapture(AudioFormat format) { public static String canBeUsedForPrivilegedMediaCapture(AudioFormat format) { int sampleRate = format.getSampleRate(); if (sampleRate > PRIVILEDGED_CAPTURE_MAX_SAMPLE_RATE || sampleRate <= 0) { return "Privileged audio capture sample rate " + sampleRate Loading Loading @@ -448,8 +448,8 @@ public class AudioMix { } } } if (mRule.allowPrivilegedPlaybackCapture()) { String error = AudioMix.canBeUsedForPrivilegedCapture(mFormat); if (mRule.allowPrivilegedMediaPlaybackCapture()) { String error = AudioMix.canBeUsedForPrivilegedMediaCapture(mFormat); if (error != null) { throw new IllegalArgumentException(error); } Loading
media/java/android/media/audiopolicy/AudioMixingRule.java +10 −6 Original line number Diff line number Diff line Loading @@ -46,11 +46,11 @@ import java.util.Objects; public class AudioMixingRule { private AudioMixingRule(int mixType, ArrayList<AudioMixMatchCriterion> criteria, boolean allowPrivilegedPlaybackCapture, boolean allowPrivilegedMediaPlaybackCapture, boolean voiceCommunicationCaptureAllowed) { mCriteria = criteria; mTargetMixType = mixType; mAllowPrivilegedPlaybackCapture = allowPrivilegedPlaybackCapture; mAllowPrivilegedPlaybackCapture = allowPrivilegedMediaPlaybackCapture; mVoiceCommunicationCaptureAllowed = voiceCommunicationCaptureAllowed; } Loading Loading @@ -204,13 +204,17 @@ public class AudioMixingRule { private final ArrayList<AudioMixMatchCriterion> mCriteria; /** @hide */ public ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; } /** Indicates that this rule is intended to capture media or game playback by a system component * with permission CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT. */ //TODO b/177061175: rename to mAllowPrivilegedMediaPlaybackCapture @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mAllowPrivilegedPlaybackCapture = false; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private boolean mVoiceCommunicationCaptureAllowed = false; /** @hide */ public boolean allowPrivilegedPlaybackCapture() { public boolean allowPrivilegedMediaPlaybackCapture() { return mAllowPrivilegedPlaybackCapture; } Loading Loading @@ -311,7 +315,7 @@ public class AudioMixingRule { public static class Builder { private ArrayList<AudioMixMatchCriterion> mCriteria; private int mTargetMixType = AudioMix.MIX_TYPE_INVALID; private boolean mAllowPrivilegedPlaybackCapture = false; private boolean mAllowPrivilegedMediaPlaybackCapture = false; // This value should be set internally according to a permission check private boolean mVoiceCommunicationCaptureAllowed = false; Loading Loading @@ -434,7 +438,7 @@ public class AudioMixingRule { * @return the same Builder instance. */ public @NonNull Builder allowPrivilegedPlaybackCapture(boolean allow) { mAllowPrivilegedPlaybackCapture = allow; mAllowPrivilegedMediaPlaybackCapture = allow; return this; } Loading Loading @@ -639,7 +643,7 @@ public class AudioMixingRule { */ public AudioMixingRule build() { return new AudioMixingRule(mTargetMixType, mCriteria, mAllowPrivilegedPlaybackCapture, mVoiceCommunicationCaptureAllowed); mAllowPrivilegedMediaPlaybackCapture, mVoiceCommunicationCaptureAllowed); } } }
media/java/android/media/audiopolicy/AudioPolicyConfig.java +2 −2 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ public class AudioPolicyConfig implements Parcelable { dest.writeInt(mix.getFormat().getEncoding()); dest.writeInt(mix.getFormat().getChannelMask()); // write opt-out respect dest.writeBoolean(mix.getRule().allowPrivilegedPlaybackCapture()); dest.writeBoolean(mix.getRule().allowPrivilegedMediaPlaybackCapture()); // write voice communication capture allowed flag dest.writeBoolean(mix.getRule().voiceCommunicationCaptureAllowed()); // write mix rules Loading Loading @@ -172,7 +172,7 @@ public class AudioPolicyConfig implements Parcelable { textDump += " channels=0x"; textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() + "\n"; textDump += " ignore playback capture opt out=" + mix.getRule().allowPrivilegedPlaybackCapture() + "\n"; + mix.getRule().allowPrivilegedMediaPlaybackCapture() + "\n"; textDump += " allow voice communication capture=" + mix.getRule().voiceCommunicationCaptureAllowed() + "\n"; // write mix rules Loading
services/core/java/com/android/server/audio/AudioService.java +20 −19 Original line number Diff line number Diff line Loading @@ -8454,21 +8454,23 @@ public class AudioService extends IAudioService.Stub } for (AudioMix mix : policyConfig.getMixes()) { // If mix is requesting privileged capture if (mix.getRule().allowPrivilegedPlaybackCapture()) { // then it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission requireCaptureAudioOrMediaOutputPerm |= true; // and its format must be low quality enough String error = mix.canBeUsedForPrivilegedCapture(mix.getFormat()); if (error != null) { Log.e(TAG, error); if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { // then its format must be low quality enough String privilegedMediaCaptureError = mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); if (privilegedMediaCaptureError != null) { Log.e(TAG, privilegedMediaCaptureError); return false; } // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission requireCaptureAudioOrMediaOutputPerm |= true; // If mix is trying to excplicitly capture USAGE_VOICE_COMMUNICATION } // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION if (mix.containsMatchAttributeRuleForUsage( AudioAttributes.USAGE_VOICE_COMMUNICATION)) { // then it must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission AudioAttributes.USAGE_VOICE_COMMUNICATION) && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced // in AudioPolicyMix if (voiceCommunicationCaptureMixes == null) { Loading @@ -8476,7 +8478,6 @@ public class AudioService extends IAudioService.Stub } voiceCommunicationCaptureMixes.add(mix); } } // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough // otherwise MODIFY_AUDIO_ROUTING permission is required Loading @@ -8498,7 +8499,7 @@ public class AudioService extends IAudioService.Stub if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { if (!callerHasPermission( android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { Log.e(TAG, "Privileged audio capture for voice communication requires " Log.e(TAG, "Audio capture for voice communication requires " + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); return false; } Loading