From cad1440e667b272c6aaf79eb9a2e07dad84cc7be Mon Sep 17 00:00:00 2001 From: ibaker Date: Mon, 30 May 2022 09:31:27 +0000 Subject: [PATCH] Wrap framework AudioAttributes in new AudioAttributesV21 class PiperOrigin-RevId: 451831531 --- RELEASENOTES.md | 3 ++ .../media3/common/AudioAttributes.java | 47 +++++++++++-------- .../media3/exoplayer/AudioFocusManager.java | 3 +- .../exoplayer/audio/DefaultAudioSink.java | 5 +- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a5c5e2ba23..4f26fe013f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -35,6 +35,9 @@ * Add AV1 support to the `MediaCodecVideoRenderer.getCodecMaxInputSize`. * Audio: * Use LG AC3 audio decoder advertising non-standard MIME type. + * Change the return type of `AudioAttributes.getAudioAttributesV21()` from + `android.media.AudioAttributes` to a new `AudioAttributesV21` wrapper + class, to prevent slow ART verification on API < 21. * Ad playback / IMA: * Decrease ad polling rate from every 100ms to every 200ms, to line up with Media Rating Council (MRC) recommendations. diff --git a/libraries/common/src/main/java/androidx/media3/common/AudioAttributes.java b/libraries/common/src/main/java/androidx/media3/common/AudioAttributes.java index 85ca196eca..b962fdc89a 100644 --- a/libraries/common/src/main/java/androidx/media3/common/AudioAttributes.java +++ b/libraries/common/src/main/java/androidx/media3/common/AudioAttributes.java @@ -42,6 +42,27 @@ import java.lang.annotation.Target; */ public final class AudioAttributes implements Bundleable { + /** A direct wrapper around {@link android.media.AudioAttributes}. */ + @RequiresApi(21) + public static final class AudioAttributesV21 { + public final android.media.AudioAttributes audioAttributes; + + private AudioAttributesV21(AudioAttributes audioAttributes) { + android.media.AudioAttributes.Builder builder = + new android.media.AudioAttributes.Builder() + .setContentType(audioAttributes.contentType) + .setFlags(audioAttributes.flags) + .setUsage(audioAttributes.usage); + if (Util.SDK_INT >= 29) { + Api29.setAllowedCapturePolicy(builder, audioAttributes.allowedCapturePolicy); + } + if (Util.SDK_INT >= 32) { + Api32.setSpatializationBehavior(builder, audioAttributes.spatializationBehavior); + } + this.audioAttributes = builder.build(); + } + } + /** * The default audio attributes, where the content type is {@link C#AUDIO_CONTENT_TYPE_UNKNOWN}, * usage is {@link C#USAGE_MEDIA}, capture policy is {@link C#ALLOW_CAPTURE_BY_ALL} and no flags @@ -120,7 +141,7 @@ public final class AudioAttributes implements Bundleable { /** The {@link C.SpatializationBehavior}. */ public final @C.SpatializationBehavior int spatializationBehavior; - @Nullable private android.media.AudioAttributes audioAttributesV21; + @Nullable private AudioAttributesV21 audioAttributesV21; private AudioAttributes( @C.AudioContentType int contentType, @@ -136,25 +157,15 @@ public final class AudioAttributes implements Bundleable { } /** - * Returns a {@link android.media.AudioAttributes} from this instance. + * Returns a {@link AudioAttributesV21} from this instance. * - *

Field {@link AudioAttributes#allowedCapturePolicy} is ignored for API levels prior to 29. + *

Some fields are ignored if the corresponding {@link android.media.AudioAttributes.Builder} + * setter is not available on the current API level. */ @RequiresApi(21) - public android.media.AudioAttributes getAudioAttributesV21() { + public AudioAttributesV21 getAudioAttributesV21() { if (audioAttributesV21 == null) { - android.media.AudioAttributes.Builder builder = - new android.media.AudioAttributes.Builder() - .setContentType(contentType) - .setFlags(flags) - .setUsage(usage); - if (Util.SDK_INT >= 29) { - Api29.setAllowedCapturePolicy(builder, allowedCapturePolicy); - } - if (Util.SDK_INT >= 32) { - Api32.setSpatializationBehavior(builder, spatializationBehavior); - } - audioAttributesV21 = builder.build(); + audioAttributesV21 = new AudioAttributesV21(this); } return audioAttributesV21; } @@ -248,8 +259,6 @@ public final class AudioAttributes implements Bundleable { @RequiresApi(29) private static final class Api29 { - private Api29() {} - @DoNotInline public static void setAllowedCapturePolicy( android.media.AudioAttributes.Builder builder, @@ -260,8 +269,6 @@ public final class AudioAttributes implements Bundleable { @RequiresApi(32) private static final class Api32 { - private Api32() {} - @DoNotInline public static void setSpatializationBehavior( android.media.AudioAttributes.Builder builder, diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java index 37544c196c..28ccfa2121 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java @@ -276,7 +276,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; boolean willPauseWhenDucked = willPauseWhenDucked(); audioFocusRequest = builder - .setAudioAttributes(checkNotNull(audioAttributes).getAudioAttributesV21()) + .setAudioAttributes( + checkNotNull(audioAttributes).getAudioAttributesV21().audioAttributes) .setWillPauseWhenDucked(willPauseWhenDucked) .setOnAudioFocusChangeListener(focusListener) .build(); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java index 3defbe3015..13c80a1228 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java @@ -1836,7 +1836,8 @@ public final class DefaultAudioSink implements AudioSink { } AudioFormat audioFormat = getAudioFormat(format.sampleRate, channelConfig, encoding); - switch (getOffloadedPlaybackSupport(audioFormat, audioAttributes.getAudioAttributesV21())) { + switch (getOffloadedPlaybackSupport( + audioFormat, audioAttributes.getAudioAttributesV21().audioAttributes)) { case AudioManager.PLAYBACK_OFFLOAD_NOT_SUPPORTED: return false; case AudioManager.PLAYBACK_OFFLOAD_SUPPORTED: @@ -2310,7 +2311,7 @@ public final class DefaultAudioSink implements AudioSink { if (tunneling) { return getAudioTrackTunnelingAttributesV21(); } else { - return audioAttributes.getAudioAttributesV21(); + return audioAttributes.getAudioAttributesV21().audioAttributes; } }