Fix audio focus handling in ExoPlayerImpl
Some cases are not handled correctly at the moment: - Pausing during suppressed playback should not clear the suppression state. - Transient focus loss while paused should be reported as a playback suppression. Issue: androidx/media#1436 #cherrypick PiperOrigin-RevId: 644971218
This commit is contained in:
parent
1d26d1891e
commit
e84bb0d21c
@ -4,6 +4,9 @@
|
||||
|
||||
* Common Library:
|
||||
* ExoPlayer:
|
||||
* Fix some audio focus inconsistencies, e.g. not reporting full or
|
||||
transient focus loss while the player is paused
|
||||
([#1436](https://github.com/androidx/media/issues/1436)).
|
||||
* Transformer:
|
||||
* Track Selection:
|
||||
* Extractors:
|
||||
|
@ -550,8 +550,7 @@ import java.util.concurrent.TimeoutException;
|
||||
boolean playWhenReady = getPlayWhenReady();
|
||||
@AudioFocusManager.PlayerCommand
|
||||
int playerCommand = audioFocusManager.updateAudioFocus(playWhenReady, Player.STATE_BUFFERING);
|
||||
updatePlayWhenReady(
|
||||
playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playWhenReady, playerCommand));
|
||||
updatePlayWhenReady(playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playerCommand));
|
||||
if (playbackInfo.playbackState != Player.STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
@ -831,8 +830,7 @@ import java.util.concurrent.TimeoutException;
|
||||
verifyApplicationThread();
|
||||
@AudioFocusManager.PlayerCommand
|
||||
int playerCommand = audioFocusManager.updateAudioFocus(playWhenReady, getPlaybackState());
|
||||
updatePlayWhenReady(
|
||||
playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playWhenReady, playerCommand));
|
||||
updatePlayWhenReady(playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playerCommand));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1500,8 +1498,7 @@ import java.util.concurrent.TimeoutException;
|
||||
boolean playWhenReady = getPlayWhenReady();
|
||||
@AudioFocusManager.PlayerCommand
|
||||
int playerCommand = audioFocusManager.updateAudioFocus(playWhenReady, getPlaybackState());
|
||||
updatePlayWhenReady(
|
||||
playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playWhenReady, playerCommand));
|
||||
updatePlayWhenReady(playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playerCommand));
|
||||
listeners.flushEvents();
|
||||
}
|
||||
|
||||
@ -2836,7 +2833,7 @@ import java.util.concurrent.TimeoutException;
|
||||
@PlaybackSuppressionReason
|
||||
private int computePlaybackSuppressionReason(
|
||||
boolean playWhenReady, @AudioFocusManager.PlayerCommand int playerCommand) {
|
||||
if (playWhenReady && playerCommand != AudioFocusManager.PLAYER_COMMAND_PLAY_WHEN_READY) {
|
||||
if (playerCommand == AudioFocusManager.PLAYER_COMMAND_WAIT_FOR_CALLBACK) {
|
||||
return Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS;
|
||||
}
|
||||
if (suppressPlaybackOnUnsuitableOutput) {
|
||||
@ -3005,8 +3002,8 @@ import java.util.concurrent.TimeoutException;
|
||||
.build();
|
||||
}
|
||||
|
||||
private static int getPlayWhenReadyChangeReason(boolean playWhenReady, int playerCommand) {
|
||||
return playWhenReady && playerCommand != AudioFocusManager.PLAYER_COMMAND_PLAY_WHEN_READY
|
||||
private static int getPlayWhenReadyChangeReason(int playerCommand) {
|
||||
return playerCommand == AudioFocusManager.PLAYER_COMMAND_DO_NOT_PLAY
|
||||
? PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS
|
||||
: PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST;
|
||||
}
|
||||
@ -3291,7 +3288,7 @@ import java.util.concurrent.TimeoutException;
|
||||
public void executePlayerCommand(@AudioFocusManager.PlayerCommand int playerCommand) {
|
||||
boolean playWhenReady = getPlayWhenReady();
|
||||
updatePlayWhenReady(
|
||||
playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playWhenReady, playerCommand));
|
||||
playWhenReady, playerCommand, getPlayWhenReadyChangeReason(playerCommand));
|
||||
}
|
||||
|
||||
// AudioBecomingNoisyManager.EventListener implementation.
|
||||
|
@ -4504,10 +4504,12 @@ public class ExoPlayerTest {
|
||||
run(player).untilPendingCommandsAreFullyHandled();
|
||||
player.pause();
|
||||
boolean playWhenReady = player.getPlayWhenReady();
|
||||
@Player.PlaybackSuppressionReason int suppressionReason = player.getPlaybackSuppressionReason();
|
||||
player.release();
|
||||
|
||||
assertThat(playWhenReady).isFalse();
|
||||
// TODO: Fix behavior and assert that suppression reason if transient audio focus loss.
|
||||
assertThat(suppressionReason)
|
||||
.isEqualTo(Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS);
|
||||
InOrder inOrder = inOrder(listener);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
@ -4607,7 +4609,10 @@ public class ExoPlayerTest {
|
||||
.verify(listener)
|
||||
.onPlayWhenReadyChanged(
|
||||
/* playWhenReady= */ false, Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
|
||||
// TODO: Fix behavior and assert that audio focus loss is reported via onPlayWhenReadyChanged.
|
||||
inOrder
|
||||
.verify(listener)
|
||||
.onPlayWhenReadyChanged(
|
||||
/* playWhenReady= */ false, Player.PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -4629,17 +4634,22 @@ public class ExoPlayerTest {
|
||||
.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
|
||||
run(player).untilPendingCommandsAreFullyHandled();
|
||||
boolean playWhenReady = player.getPlayWhenReady();
|
||||
@Player.PlaybackSuppressionReason int suppressionReason = player.getPlaybackSuppressionReason();
|
||||
shadowOf(audioManager)
|
||||
.getLastAudioFocusRequest()
|
||||
.listener
|
||||
.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN);
|
||||
run(player).untilPendingCommandsAreFullyHandled();
|
||||
boolean playWhenReadyAfterGain = player.getPlayWhenReady();
|
||||
@Player.PlaybackSuppressionReason
|
||||
int suppressionReasonAfterGain = player.getPlaybackSuppressionReason();
|
||||
player.release();
|
||||
|
||||
assertThat(playWhenReady).isFalse();
|
||||
assertThat(playWhenReadyAfterGain).isFalse();
|
||||
// TODO: Fix behavior and assert that suppression reason is transient audio focus loss.
|
||||
assertThat(suppressionReason)
|
||||
.isEqualTo(Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS);
|
||||
assertThat(suppressionReasonAfterGain).isEqualTo(Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||
InOrder inOrder = inOrder(listener);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
@ -4649,6 +4659,13 @@ public class ExoPlayerTest {
|
||||
.verify(listener)
|
||||
.onPlayWhenReadyChanged(
|
||||
/* playWhenReady= */ false, Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
.onPlaybackSuppressionReasonChanged(
|
||||
Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
.onPlaybackSuppressionReasonChanged(Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||
verify(listener, never())
|
||||
.onPlayWhenReadyChanged(
|
||||
/* playWhenReady= */ false, Player.PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS);
|
||||
@ -4679,7 +4696,6 @@ public class ExoPlayerTest {
|
||||
|
||||
assertThat(playWhenReady).isTrue();
|
||||
assertThat(suppressionReason).isEqualTo(Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||
// TODO: Fix behavior and assert that suppression reason is transient audio focus loss.
|
||||
InOrder inOrder = inOrder(listener);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
@ -4689,10 +4705,17 @@ public class ExoPlayerTest {
|
||||
.verify(listener)
|
||||
.onPlayWhenReadyChanged(
|
||||
/* playWhenReady= */ false, Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
.onPlaybackSuppressionReasonChanged(
|
||||
Player.PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
.onPlayWhenReadyChanged(
|
||||
/* playWhenReady= */ true, Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
|
||||
inOrder
|
||||
.verify(listener)
|
||||
.onPlaybackSuppressionReasonChanged(Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||
verify(listener, never())
|
||||
.onPlayWhenReadyChanged(
|
||||
/* playWhenReady= */ false, Player.PLAY_WHEN_READY_CHANGE_REASON_AUDIO_FOCUS_LOSS);
|
||||
|
Loading…
x
Reference in New Issue
Block a user