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
This commit is contained in:
jbibik 2024-09-10 08:02:20 -07:00 committed by Copybara-Service
parent a53ea621bb
commit 8bfa7e2de1
4 changed files with 46 additions and 7 deletions

View File

@ -56,7 +56,8 @@ public class StreamVolumeManagerTest {
testThread.runOnMainThread( testThread.runOnMainThread(
() -> () ->
streamVolumeManager = streamVolumeManager =
new StreamVolumeManager(context, new Handler(Looper.myLooper()), testListener)); new StreamVolumeManager(
context, new Handler(Looper.myLooper()), testListener, C.STREAM_TYPE_DEFAULT));
} }
@After @After
@ -230,7 +231,7 @@ public class StreamVolumeManagerTest {
} }
@Test @Test
public void setStreamType_notifiesStreamTypeAndVolume() { public void setStreamType_toNonDefaultType_notifiesStreamTypeAndVolume() {
testThread.runOnMainThread( testThread.runOnMainThread(
() -> { () -> {
int minVolume = streamVolumeManager.getMinVolume(); int minVolume = streamVolumeManager.getMinVolume();
@ -240,7 +241,7 @@ public class StreamVolumeManagerTest {
} }
int volumeFlags = C.VOLUME_FLAG_SHOW_UI | C.VOLUME_FLAG_VIBRATE; 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 testStreamVolume = audioManager.getStreamVolume(testStreamType);
int oldVolume = streamVolumeManager.getVolume(); int oldVolume = streamVolumeManager.getVolume();

View File

@ -415,8 +415,11 @@ import java.util.concurrent.TimeoutException;
if (builder.deviceVolumeControlEnabled) { if (builder.deviceVolumeControlEnabled) {
streamVolumeManager = streamVolumeManager =
new StreamVolumeManager(builder.context, eventHandler, componentListener); new StreamVolumeManager(
streamVolumeManager.setStreamType(Util.getStreamTypeForAudioUsage(audioAttributes.usage)); builder.context,
eventHandler,
componentListener,
Util.getStreamTypeForAudioUsage(audioAttributes.usage));
} else { } else {
streamVolumeManager = null; streamVolumeManager = null;
} }

View File

@ -57,7 +57,8 @@ import androidx.media3.common.util.Util;
private boolean muted; private boolean muted;
/** Creates a manager. */ /** 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(); applicationContext = context.getApplicationContext();
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.listener = listener; this.listener = listener;
@ -65,7 +66,7 @@ import androidx.media3.common.util.Util;
Assertions.checkStateNotNull( Assertions.checkStateNotNull(
(AudioManager) applicationContext.getSystemService(Context.AUDIO_SERVICE)); (AudioManager) applicationContext.getSystemService(Context.AUDIO_SERVICE));
streamType = C.STREAM_TYPE_DEFAULT; this.streamType = streamType;
volume = getVolumeFromManager(audioManager, streamType); volume = getVolumeFromManager(audioManager, streamType);
muted = getMutedFromManager(audioManager, streamType); muted = getMutedFromManager(audioManager, streamType);

View File

@ -15772,6 +15772,40 @@ public class ExoPlayerTest {
assertThat(mediaItemIndexAfterReprepare).isEqualTo(0); 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. // Internal methods.
private void addWatchAsSystemFeature() { private void addWatchAsSystemFeature() {