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 26b04f5a22..9520bd217d 100644 --- a/libraries/common/src/main/java/androidx/media3/common/AudioAttributes.java +++ b/libraries/common/src/main/java/androidx/media3/common/AudioAttributes.java @@ -66,12 +66,14 @@ public static final class Builder { private @C.AudioAllowedCapturePolicy int allowedCapturePolicy; private @C.SpatializationBehavior int spatializationBehavior; private boolean isContentSpatialized; + private boolean hapticChannelsMuted; /** * Creates a new builder for {@link AudioAttributes}. * *

By default 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 are set. + * C#USAGE_MEDIA}, capture policy is {@link C#ALLOW_CAPTURE_BY_ALL}, no flags are set and haptic + * channels are muted. */ public Builder() { contentType = C.AUDIO_CONTENT_TYPE_UNKNOWN; @@ -80,6 +82,7 @@ public Builder() { allowedCapturePolicy = C.ALLOW_CAPTURE_BY_ALL; spatializationBehavior = C.SPATIALIZATION_BEHAVIOR_AUTO; isContentSpatialized = false; + hapticChannelsMuted = true; } /** See {@link android.media.AudioAttributes.Builder#setContentType(int)} */ @@ -125,6 +128,14 @@ public Builder setIsContentSpatialized(boolean isContentSpatialized) { return this; } + /** See {@link android.media.AudioAttributes.Builder#setHapticChannelsMuted(boolean)}. */ + @CanIgnoreReturnValue + @UnstableApi + public Builder setHapticChannelsMuted(boolean hapticChannelsMuted) { + this.hapticChannelsMuted = hapticChannelsMuted; + return this; + } + /** Creates an {@link AudioAttributes} instance from this builder. */ public AudioAttributes build() { return new AudioAttributes( @@ -133,7 +144,8 @@ public AudioAttributes build() { usage, allowedCapturePolicy, spatializationBehavior, - isContentSpatialized); + isContentSpatialized, + hapticChannelsMuted); } } @@ -148,6 +160,7 @@ public static AudioAttributes fromPlatformAudioAttributes( .setUsage(audioAttributes.getUsage()); if (SDK_INT >= 29) { builder.setAllowedCapturePolicy(audioAttributes.getAllowedCapturePolicy()); + builder.setHapticChannelsMuted(audioAttributes.areHapticChannelsMuted()); } if (SDK_INT >= 32) { builder.setSpatializationBehavior(audioAttributes.getSpatializationBehavior()); @@ -174,6 +187,9 @@ public static AudioAttributes fromPlatformAudioAttributes( /** Whether the content is spatialized. */ @UnstableApi public final boolean isContentSpatialized; + /** Whether haptic channels are muted. */ + @UnstableApi public final boolean hapticChannelsMuted; + @Nullable private android.media.AudioAttributes platformAudioAttributes; private AudioAttributes( @@ -182,13 +198,15 @@ private AudioAttributes( @C.AudioUsage int usage, @C.AudioAllowedCapturePolicy int allowedCapturePolicy, @C.SpatializationBehavior int spatializationBehavior, - boolean isContentSpatialized) { + boolean isContentSpatialized, + boolean hapticChannelsMuted) { this.contentType = contentType; this.flags = flags; this.usage = usage; this.allowedCapturePolicy = allowedCapturePolicy; this.spatializationBehavior = spatializationBehavior; this.isContentSpatialized = isContentSpatialized; + this.hapticChannelsMuted = hapticChannelsMuted; } /** @@ -216,6 +234,7 @@ public android.media.AudioAttributes getPlatformAudioAttributes() { .setUsage(usage); if (SDK_INT >= 29) { Api29.setAllowedCapturePolicy(builder, allowedCapturePolicy); + Api29.setHapticChannelsMuted(builder, hapticChannelsMuted); } if (SDK_INT >= 32) { Api32.setSpatializationBehavior(builder, spatializationBehavior); @@ -277,7 +296,8 @@ public boolean equals(@Nullable Object obj) { && this.usage == other.usage && this.allowedCapturePolicy == other.allowedCapturePolicy && this.spatializationBehavior == other.spatializationBehavior - && this.isContentSpatialized == other.isContentSpatialized; + && this.isContentSpatialized == other.isContentSpatialized + && this.hapticChannelsMuted == other.hapticChannelsMuted; } @Override @@ -289,6 +309,7 @@ public int hashCode() { result = 31 * result + allowedCapturePolicy; result = 31 * result + spatializationBehavior; result = 31 * result + (isContentSpatialized ? 1 : 0); + result = 31 * result + (hapticChannelsMuted ? 1 : 0); return result; } @@ -298,6 +319,7 @@ public int hashCode() { private static final String FIELD_ALLOWED_CAPTURE_POLICY = Util.intToStringMaxRadix(3); private static final String FIELD_SPATIALIZATION_BEHAVIOR = Util.intToStringMaxRadix(4); private static final String FIELD_IS_CONTENT_SPATIALIZED = Util.intToStringMaxRadix(5); + private static final String FIELD_HAPTIC_CHANNELS_MUTED = Util.intToStringMaxRadix(6); @UnstableApi public Bundle toBundle() { @@ -308,6 +330,9 @@ public Bundle toBundle() { bundle.putInt(FIELD_ALLOWED_CAPTURE_POLICY, allowedCapturePolicy); bundle.putInt(FIELD_SPATIALIZATION_BEHAVIOR, spatializationBehavior); bundle.putBoolean(FIELD_IS_CONTENT_SPATIALIZED, isContentSpatialized); + if (!hapticChannelsMuted) { + bundle.putBoolean(FIELD_HAPTIC_CHANNELS_MUTED, hapticChannelsMuted); + } return bundle; } @@ -333,6 +358,9 @@ public static AudioAttributes fromBundle(Bundle bundle) { if (bundle.containsKey(FIELD_IS_CONTENT_SPATIALIZED)) { builder.setIsContentSpatialized(bundle.getBoolean(FIELD_IS_CONTENT_SPATIALIZED)); } + if (bundle.containsKey(FIELD_HAPTIC_CHANNELS_MUTED)) { + builder.setHapticChannelsMuted(bundle.getBoolean(FIELD_HAPTIC_CHANNELS_MUTED)); + } return builder.build(); } @@ -344,6 +372,11 @@ public static void setAllowedCapturePolicy( @C.AudioAllowedCapturePolicy int allowedCapturePolicy) { builder.setAllowedCapturePolicy(allowedCapturePolicy); } + + private static void setHapticChannelsMuted( + android.media.AudioAttributes.Builder builder, boolean hapticChannelsMuted) { + builder.setHapticChannelsMuted(hapticChannelsMuted); + } } @RequiresApi(32) diff --git a/libraries/common/src/test/java/androidx/media3/common/AudioAttributesTest.java b/libraries/common/src/test/java/androidx/media3/common/AudioAttributesTest.java index 165fafd985..01ccfeb06d 100644 --- a/libraries/common/src/test/java/androidx/media3/common/AudioAttributesTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/AudioAttributesTest.java @@ -38,6 +38,7 @@ public void roundTripViaBundle_yieldsEqualInstance() { .setAllowedCapturePolicy(C.ALLOW_CAPTURE_BY_SYSTEM) .setSpatializationBehavior(C.SPATIALIZATION_BEHAVIOR_NEVER) .setIsContentSpatialized(true) + .setHapticChannelsMuted(false) .build(); assertThat(AudioAttributes.fromBundle(audioAttributes.toBundle())).isEqualTo(audioAttributes); @@ -66,12 +67,14 @@ public void fromPlatformAudioAttributesV29_setsCorrectValues() { android.media.AudioAttributes platformAttributes = new android.media.AudioAttributes.Builder() .setAllowedCapturePolicy(android.media.AudioAttributes.ALLOW_CAPTURE_BY_SYSTEM) + .setHapticChannelsMuted(false) .build(); AudioAttributes audioAttributes = AudioAttributes.fromPlatformAudioAttributes(platformAttributes); assertThat(audioAttributes.allowedCapturePolicy).isEqualTo(C.ALLOW_CAPTURE_BY_SYSTEM); + assertThat(audioAttributes.hapticChannelsMuted).isFalse(); } @Config(minSdk = 32) @@ -99,7 +102,8 @@ public void builder_setsCorrectValues() { .setFlags(C.FLAG_AUDIBILITY_ENFORCED) .setAllowedCapturePolicy(C.ALLOW_CAPTURE_BY_SYSTEM) .setIsContentSpatialized(true) - .setSpatializationBehavior(C.SPATIALIZATION_BEHAVIOR_NEVER); + .setSpatializationBehavior(C.SPATIALIZATION_BEHAVIOR_NEVER) + .setHapticChannelsMuted(false); AudioAttributes audioAttributes = builder.build(); @@ -109,6 +113,7 @@ public void builder_setsCorrectValues() { assertThat(audioAttributes.allowedCapturePolicy).isEqualTo(C.ALLOW_CAPTURE_BY_SYSTEM); assertThat(audioAttributes.spatializationBehavior).isEqualTo(C.SPATIALIZATION_BEHAVIOR_NEVER); assertThat(audioAttributes.isContentSpatialized).isTrue(); + assertThat(audioAttributes.hapticChannelsMuted).isFalse(); } @Test