diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 37d29c1494..c39f102309 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -34,6 +34,11 @@ API 35+ (where the device advertises support for this). * Handle preload callbacks asynchronously in `PreloadMediaSource` ([#1568](https://github.com/androidx/media/issues/1568)). + * Defer the blocking call to + `Context.getSystemService(Context.AUDIO_SERVICE)` until audio focus + handling is enabled. This ensures the blocking call isn't done if audio + focus handling is not enabled + ([#1616](https://github.com/androidx/media/pull/1616)). * Transformer: * Add `SurfaceAssetLoader`, which supports queueing video data to Transformer via a `Surface`. 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 fb9823beba..c82281cae4 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java @@ -32,6 +32,8 @@ import androidx.media3.common.Player; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Log; import androidx.media3.common.util.Util; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -160,7 +162,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private static final float VOLUME_MULTIPLIER_DUCK = 0.2f; private static final float VOLUME_MULTIPLIER_DEFAULT = 1.0f; - private final AudioManager audioManager; + private final Supplier audioManager; private final AudioFocusListener focusListener; @Nullable private PlayerControl playerControl; @Nullable private AudioAttributes audioAttributes; @@ -168,7 +170,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private @AudioFocusState int audioFocusState; private @AudioFocusGain int focusGainToRequest; private float volumeMultiplier = VOLUME_MULTIPLIER_DEFAULT; - private @MonotonicNonNull AudioFocusRequest audioFocusRequest; private boolean rebuildAudioFocusRequest; @@ -181,8 +182,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; */ public AudioFocusManager(Context context, Handler eventHandler, PlayerControl playerControl) { this.audioManager = - checkNotNull( - (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)); + Suppliers.memoize( + () -> + checkNotNull( + (AudioManager) + context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE))); this.playerControl = playerControl; this.focusListener = new AudioFocusListener(eventHandler); this.audioFocusState = AUDIO_FOCUS_STATE_NOT_REQUESTED; @@ -287,10 +291,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } private int requestAudioFocusDefault() { - return audioManager.requestAudioFocus( - focusListener, - Util.getStreamTypeForAudioUsage(checkNotNull(audioAttributes).usage), - focusGainToRequest); + return audioManager + .get() + .requestAudioFocus( + focusListener, + Util.getStreamTypeForAudioUsage(checkNotNull(audioAttributes).usage), + focusGainToRequest); } @RequiresApi(26) @@ -312,17 +318,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; rebuildAudioFocusRequest = false; } - return audioManager.requestAudioFocus(audioFocusRequest); + return audioManager.get().requestAudioFocus(audioFocusRequest); } private void abandonAudioFocusDefault() { - audioManager.abandonAudioFocus(focusListener); + audioManager.get().abandonAudioFocus(focusListener); } @RequiresApi(26) private void abandonAudioFocusV26() { if (audioFocusRequest != null) { - audioManager.abandonAudioFocusRequest(audioFocusRequest); + audioManager.get().abandonAudioFocusRequest(audioFocusRequest); } }