From 8bfa7e2de1cea79b72bc923d7993b55d09d35b2b Mon Sep 17 00:00:00 2001 From: jbibik Date: Tue, 10 Sep 2024 08:02:20 -0700 Subject: [PATCH] Make StreamVolumeManager take streamType in constructor Avoids the dispatch of listener notifications of stream type/device volume change during construction of ExoPlayer. That was problematic because we end up blocking on `constructorFinished.blockUninterruptible()` Issue: androidx/media#1692 PiperOrigin-RevId: 672965552 --- .../exoplayer/StreamVolumeManagerTest.java | 7 ++-- .../media3/exoplayer/ExoPlayerImpl.java | 7 ++-- .../media3/exoplayer/StreamVolumeManager.java | 5 +-- .../media3/exoplayer/ExoPlayerTest.java | 34 +++++++++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/StreamVolumeManagerTest.java b/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/StreamVolumeManagerTest.java index e7dd210ddb..b19dfc243b 100644 --- a/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/StreamVolumeManagerTest.java +++ b/libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/StreamVolumeManagerTest.java @@ -56,7 +56,8 @@ public class StreamVolumeManagerTest { testThread.runOnMainThread( () -> streamVolumeManager = - new StreamVolumeManager(context, new Handler(Looper.myLooper()), testListener)); + new StreamVolumeManager( + context, new Handler(Looper.myLooper()), testListener, C.STREAM_TYPE_DEFAULT)); } @After @@ -230,7 +231,7 @@ public class StreamVolumeManagerTest { } @Test - public void setStreamType_notifiesStreamTypeAndVolume() { + public void setStreamType_toNonDefaultType_notifiesStreamTypeAndVolume() { testThread.runOnMainThread( () -> { int minVolume = streamVolumeManager.getMinVolume(); @@ -240,7 +241,7 @@ public class StreamVolumeManagerTest { } int volumeFlags = C.VOLUME_FLAG_SHOW_UI | C.VOLUME_FLAG_VIBRATE; - int testStreamType = C.STREAM_TYPE_ALARM; + int testStreamType = C.STREAM_TYPE_ALARM; // not STREAM_TYPE_DEFAULT, i.e. MUSIC int testStreamVolume = audioManager.getStreamVolume(testStreamType); int oldVolume = streamVolumeManager.getVolume(); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java index 87abd7c4fb..369f463225 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java @@ -415,8 +415,11 @@ import java.util.concurrent.TimeoutException; if (builder.deviceVolumeControlEnabled) { streamVolumeManager = - new StreamVolumeManager(builder.context, eventHandler, componentListener); - streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage)); + new StreamVolumeManager( + builder.context, + eventHandler, + componentListener, + Util.getStreamTypeForAudioUsage(audioAttributes.usage)); } else { streamVolumeManager = null; } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/StreamVolumeManager.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/StreamVolumeManager.java index 03b65cc63e..82157c1d91 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/StreamVolumeManager.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/StreamVolumeManager.java @@ -57,7 +57,8 @@ import androidx.media3.common.util.Util; private boolean muted; /** Creates a manager. */ - public StreamVolumeManager(Context context, Handler eventHandler, Listener listener) { + public StreamVolumeManager( + Context context, Handler eventHandler, Listener listener, @C.StreamType int streamType) { applicationContext = context.getApplicationContext(); this.eventHandler = eventHandler; this.listener = listener; @@ -65,7 +66,7 @@ import androidx.media3.common.util.Util; Assertions.checkStateNotNull( (AudioManager) applicationContext.getSystemService(Context.AUDIO_SERVICE)); - streamType = C.STREAM_TYPE_DEFAULT; + this.streamType = streamType; volume = getVolumeFromManager(audioManager, streamType); muted = getMutedFromManager(audioManager, streamType); diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java index 751fbd8cf2..0c8b42d7b0 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java @@ -15772,6 +15772,40 @@ public class ExoPlayerTest { assertThat(mediaItemIndexAfterReprepare).isEqualTo(0); } + // https://github.com/androidx/media/issues/1692 + @Test + public void setAlarmAudioWithDeviceVolumeControl_exoPlayerIsConstructedWithNoDeviceUpdates() + throws Exception { + AtomicBoolean deviceInfoChanged = new AtomicBoolean(); + AtomicBoolean deviceVolumeChanged = new AtomicBoolean(); + Player.Listener listener = + new Player.Listener() { + @Override + public void onDeviceInfoChanged(DeviceInfo deviceInfo) { + deviceInfoChanged.set(true); + } + + @Override + public void onDeviceVolumeChanged(int volume, boolean muted) { + deviceVolumeChanged.set(true); + } + }; + AudioAttributes nonDefaultAudioAttributes = + new AudioAttributes.Builder() + .setUsage(C.USAGE_ALARM) // not default (USAGE_MEDIA) + .build(); + + ExoPlayer player = + new ExoPlayer.Builder(ApplicationProvider.getApplicationContext()) + .setDeviceVolumeControlEnabled(true) + .setAudioAttributes(nonDefaultAudioAttributes, /* handleAudioFocus= */ false) + .build(); + player.addListener(listener); + + assertThat(deviceInfoChanged.get()).isFalse(); + assertThat(deviceVolumeChanged.get()).isFalse(); + } + // Internal methods. private void addWatchAsSystemFeature() {