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(
() ->
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();

View File

@ -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;
}

View File

@ -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);

View File

@ -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() {