mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Update playback suppression states dynamically.
Instead of playing or pausing itself, the ExoPlayer implementation should only update the playback suppression reason as and when audio outputs are added or removed dynamically. PiperOrigin-RevId: 544379033
This commit is contained in:
parent
4e4045b98e
commit
832d5b5f98
@ -19,12 +19,9 @@
|
|||||||
`ExoPlayer.Builder.setSuppressPlaybackOnUnsuitableOutput`. The playback
|
`ExoPlayer.Builder.setSuppressPlaybackOnUnsuitableOutput`. The playback
|
||||||
suppression reason will be updated as
|
suppression reason will be updated as
|
||||||
`Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT` if playback
|
`Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT` if playback
|
||||||
is attempted when no suitable audio outputs are available.
|
is attempted when no suitable audio outputs are available, or if all
|
||||||
* Add handling for auto-resume or auto-pause of playback when audio output
|
suitable outputs are disconnected during playback. The suppression
|
||||||
devices are added or removed dynamically during suppressed or ongoing
|
reason will be removed when a suitable output is connected.
|
||||||
playback when the playback suppression due to no suitable output has
|
|
||||||
been enabled via
|
|
||||||
`ExoPlayer.Builder.setSuppressPlaybackOnUnsuitableOutput`.
|
|
||||||
* Fix issue in `PlaybackStatsListener` where spurious `PlaybackStats` are
|
* Fix issue in `PlaybackStatsListener` where spurious `PlaybackStats` are
|
||||||
created after the playlist is cleared.
|
created after the playlist is cleared.
|
||||||
* Transformer:
|
* Transformer:
|
||||||
@ -100,12 +97,6 @@
|
|||||||
tests and Compose UI tests. This fixes a bug where playback advances
|
tests and Compose UI tests. This fixes a bug where playback advances
|
||||||
non-deterministically during Espresso or Compose view interactions.
|
non-deterministically during Espresso or Compose view interactions.
|
||||||
* Remove deprecated symbols:
|
* Remove deprecated symbols:
|
||||||
* Remove
|
|
||||||
`TransformationRequest.Builder.setEnableRequestSdrToneMapping(boolean)`
|
|
||||||
and
|
|
||||||
`TransformationRequest.Builder.experimental_setEnableHdrEditing(boolean)`.
|
|
||||||
Use `Composition.Builder.setHdrMode(int)` and pass the `Composition` to
|
|
||||||
`Transformer.start(Composition, String)` instead.
|
|
||||||
|
|
||||||
## 1.1
|
## 1.1
|
||||||
|
|
||||||
|
@ -723,6 +723,9 @@ public interface ExoPlayer extends Player {
|
|||||||
* Player.Listener#onPlaybackSuppressionReasonChanged(int)} with the value {@link
|
* Player.Listener#onPlaybackSuppressionReasonChanged(int)} with the value {@link
|
||||||
* Player#PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT}.
|
* Player#PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT}.
|
||||||
*
|
*
|
||||||
|
* <p>Callers of this may also want to enable {@link #setHandleAudioBecomingNoisy(boolean)} to
|
||||||
|
* prevent playback from continuing on the built-in speaker when a headset is disconnected.
|
||||||
|
*
|
||||||
* @param suppressPlaybackOnUnsuitableOutput Whether the player should suppress the playback
|
* @param suppressPlaybackOnUnsuitableOutput Whether the player should suppress the playback
|
||||||
* when it is attempted on an unsuitable output.
|
* when it is attempted on an unsuitable output.
|
||||||
* @return This builder.
|
* @return This builder.
|
||||||
|
@ -2748,6 +2748,14 @@ import java.util.concurrent.TimeoutException;
|
|||||||
&& playbackInfo.playbackSuppressionReason == playbackSuppressionReason) {
|
&& playbackInfo.playbackSuppressionReason == playbackSuppressionReason) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
updatePlaybackInfoForPlayWhenReadyAndSuppressionReasonStates(
|
||||||
|
playWhenReady, playWhenReadyChangeReason, playbackSuppressionReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePlaybackInfoForPlayWhenReadyAndSuppressionReasonStates(
|
||||||
|
boolean playWhenReady,
|
||||||
|
@Player.PlayWhenReadyChangeReason int playWhenReadyChangeReason,
|
||||||
|
@PlaybackSuppressionReason int playbackSuppressionReason) {
|
||||||
pendingOperationAcks++;
|
pendingOperationAcks++;
|
||||||
// Position estimation and copy must occur before changing/masking playback state.
|
// Position estimation and copy must occur before changing/masking playback state.
|
||||||
PlaybackInfo newPlaybackInfo =
|
PlaybackInfo newPlaybackInfo =
|
||||||
@ -3368,14 +3376,20 @@ import java.util.concurrent.TimeoutException;
|
|||||||
if (hasSupportedAudioOutput()
|
if (hasSupportedAudioOutput()
|
||||||
&& playbackInfo.playbackSuppressionReason
|
&& playbackInfo.playbackSuppressionReason
|
||||||
== Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT) {
|
== Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT) {
|
||||||
play();
|
updatePlaybackInfoForPlayWhenReadyAndSuppressionReasonStates(
|
||||||
|
playbackInfo.playWhenReady,
|
||||||
|
PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
||||||
|
Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
|
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
|
||||||
if (!hasSupportedAudioOutput()) {
|
if (!hasSupportedAudioOutput()) {
|
||||||
pause();
|
updatePlaybackInfoForPlayWhenReadyAndSuppressionReasonStates(
|
||||||
|
playbackInfo.playWhenReady,
|
||||||
|
PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
||||||
|
Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13313,151 +13313,119 @@ public final class ExoPlayerTest {
|
|||||||
player.release();
|
player.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests removal of playback suppression reason as {@link
|
||||||
|
* Player#PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT} when a suitable device is added.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void addSuitableDevicesWhenPlaybackSuppressed_shouldRemovePlaybackSuppression()
|
||||||
onAudioDeviceAdded_addSuitableDevicesWhenPlaybackSuppressed_shouldResumeSuppressedPlayback()
|
throws Exception {
|
||||||
throws Exception {
|
|
||||||
addWatchAsSystemFeature();
|
addWatchAsSystemFeature();
|
||||||
setupConnectedAudioOutput(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
|
setupConnectedAudioOutput(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
|
||||||
ExoPlayer player =
|
ExoPlayer player =
|
||||||
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
||||||
player.setMediaItem(
|
player.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
|
List<Integer> playbackSuppressionList = new ArrayList<>();
|
||||||
|
player.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) {
|
||||||
|
playbackSuppressionList.add(playbackSuppressionReason);
|
||||||
|
}
|
||||||
|
});
|
||||||
player.prepare();
|
player.prepare();
|
||||||
player.play();
|
player.play();
|
||||||
player.pause();
|
player.pause();
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
runUntilPlaybackState(player, Player.STATE_READY);
|
||||||
AtomicBoolean isPlaybackResumed = new AtomicBoolean(false);
|
|
||||||
player.addListener(
|
|
||||||
new Player.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onPlayWhenReadyChanged(
|
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
|
||||||
if (playWhenReady
|
|
||||||
&& player.getPlaybackSuppressionReason()
|
|
||||||
!= Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT) {
|
|
||||||
isPlaybackResumed.set(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addConnectedAudioOutput(
|
addConnectedAudioOutput(
|
||||||
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
||||||
player.stop();
|
player.stop();
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
runUntilPlaybackState(player, Player.STATE_IDLE);
|
||||||
|
|
||||||
assertThat(isPlaybackResumed.get()).isTrue();
|
assertThat(playbackSuppressionList)
|
||||||
|
.containsExactly(
|
||||||
|
Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT,
|
||||||
|
Player.PLAYBACK_SUPPRESSION_REASON_NONE);
|
||||||
player.release();
|
player.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests no change in the playback suppression reason when an unsuitable device is connected while
|
||||||
|
* playback was suppressed earlier.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void addUnsuitableDevicesWithPlaybackSuppressed_shouldNotRemovePlaybackSuppression()
|
||||||
onAudioDeviceAdded_addUnsuitableDevicesWithPlaybackSuppressed_shouldNotResumePlayback()
|
throws Exception {
|
||||||
throws Exception {
|
|
||||||
addWatchAsSystemFeature();
|
addWatchAsSystemFeature();
|
||||||
setupConnectedAudioOutput(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
|
setupConnectedAudioOutput(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
|
||||||
ExoPlayer player =
|
ExoPlayer player =
|
||||||
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
||||||
player.setMediaItem(
|
player.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
player.prepare();
|
List<Integer> playbackSuppressionList = new ArrayList<>();
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
|
||||||
AtomicBoolean isPlaybackResumed = new AtomicBoolean(false);
|
|
||||||
player.addListener(
|
player.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(
|
public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) {
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
playbackSuppressionList.add(playbackSuppressionReason);
|
||||||
if (playWhenReady
|
|
||||||
&& player.getPlaybackSuppressionReason()
|
|
||||||
!= Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT) {
|
|
||||||
isPlaybackResumed.set(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
player.prepare();
|
||||||
|
player.play();
|
||||||
|
runUntilPlaybackState(player, Player.STATE_READY);
|
||||||
|
|
||||||
addConnectedAudioOutput(AudioDeviceInfo.TYPE_UNKNOWN, /* notifyAudioDeviceCallbacks= */ true);
|
addConnectedAudioOutput(AudioDeviceInfo.TYPE_UNKNOWN, /* notifyAudioDeviceCallbacks= */ true);
|
||||||
player.stop();
|
player.stop();
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
runUntilPlaybackState(player, Player.STATE_IDLE);
|
||||||
|
|
||||||
assertThat(isPlaybackResumed.get()).isFalse();
|
assertThat(playbackSuppressionList)
|
||||||
|
.containsExactly(Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT);
|
||||||
player.release();
|
player.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests no change in the playback suppression reason when a suitable device is added but playback
|
||||||
|
* was not suppressed earlier.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void addSuitableDevicesWhenPlaybackNotSuppressed_shouldNotRemovePlaybackSuppression()
|
||||||
onAudioDeviceAdded_addSuitableDevicesWhenPlaybackNotSuppressed_shouldNotResumePlayback()
|
throws Exception {
|
||||||
throws Exception {
|
|
||||||
addWatchAsSystemFeature();
|
addWatchAsSystemFeature();
|
||||||
setupConnectedAudioOutput(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
|
setupConnectedAudioOutput(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
|
||||||
ExoPlayer player =
|
ExoPlayer player =
|
||||||
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
||||||
player.setMediaItem(
|
player.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
player.prepare();
|
List<Integer> playbackSuppressionList = new ArrayList<>();
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
|
||||||
AtomicBoolean isPlaybackResumed = new AtomicBoolean(false);
|
|
||||||
player.addListener(
|
player.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(
|
public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) {
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
playbackSuppressionList.add(playbackSuppressionReason);
|
||||||
if (playWhenReady
|
|
||||||
&& player.getPlaybackSuppressionReason()
|
|
||||||
!= Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT) {
|
|
||||||
isPlaybackResumed.set(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
player.prepare();
|
||||||
|
runUntilPlaybackState(player, Player.STATE_READY);
|
||||||
|
|
||||||
addConnectedAudioOutput(
|
addConnectedAudioOutput(
|
||||||
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
||||||
player.stop();
|
player.stop();
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
runUntilPlaybackState(player, Player.STATE_IDLE);
|
||||||
|
|
||||||
assertThat(isPlaybackResumed.get()).isFalse();
|
assertThat(playbackSuppressionList).isEmpty();
|
||||||
player.release();
|
player.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests change in the playback suppression reason as {@link
|
||||||
|
* Player#PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT} when all the suitable audio outputs
|
||||||
|
* have been removed during an ongoing playback.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void onAudioDeviceAdded_addSuitableDevicesOnNonWearSurface_shouldResumeSuppressedPlayback()
|
public void removeAllSuitableDevicesWhenPlaybackOngoing_shouldSetPlaybackSuppression()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
setupConnectedAudioOutput(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
|
|
||||||
ExoPlayer player =
|
|
||||||
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
|
||||||
player.setMediaItem(
|
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
|
||||||
player.prepare();
|
|
||||||
player.play();
|
|
||||||
player.pause();
|
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
|
||||||
AtomicBoolean isPlaybackResumed = new AtomicBoolean(false);
|
|
||||||
player.addListener(
|
|
||||||
new Player.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onPlayWhenReadyChanged(
|
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
|
||||||
if (playWhenReady
|
|
||||||
&& player.getPlaybackSuppressionReason()
|
|
||||||
!= Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT) {
|
|
||||||
isPlaybackResumed.set(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addConnectedAudioOutput(
|
|
||||||
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
|
||||||
player.stop();
|
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
|
||||||
|
|
||||||
assertThat(isPlaybackResumed.get()).isFalse();
|
|
||||||
player.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void
|
|
||||||
onAudioDeviceRemoved_removeSuitableDeviceWhenPlaybackOngoing_shouldPauseOngoingPlayback()
|
|
||||||
throws Exception {
|
|
||||||
addWatchAsSystemFeature();
|
addWatchAsSystemFeature();
|
||||||
setupConnectedAudioOutput(
|
setupConnectedAudioOutput(
|
||||||
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
|
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
|
||||||
@ -13468,15 +13436,12 @@ public final class ExoPlayerTest {
|
|||||||
player.prepare();
|
player.prepare();
|
||||||
player.play();
|
player.play();
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
runUntilPlaybackState(player, Player.STATE_READY);
|
||||||
AtomicBoolean isPlaybackPaused = new AtomicBoolean(false);
|
List<Integer> playbackSuppressionList = new ArrayList<>();
|
||||||
player.addListener(
|
player.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(
|
public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) {
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
playbackSuppressionList.add(playbackSuppressionReason);
|
||||||
if (!playWhenReady) {
|
|
||||||
isPlaybackPaused.set(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -13484,14 +13449,18 @@ public final class ExoPlayerTest {
|
|||||||
player.stop();
|
player.stop();
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
runUntilPlaybackState(player, Player.STATE_IDLE);
|
||||||
|
|
||||||
assertThat(isPlaybackPaused.get()).isTrue();
|
assertThat(playbackSuppressionList)
|
||||||
|
.containsExactly(Player.PLAYBACK_SUPPRESSION_REASON_UNSUITABLE_AUDIO_OUTPUT);
|
||||||
player.release();
|
player.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests no change in the playback suppression reason when any unsuitable audio outputs has been
|
||||||
|
* removed during an ongoing playback.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void removeAnyUnsuitableDevicesWhenPlaybackOngoing_shouldNotSetPlaybackSuppression()
|
||||||
onAudioDeviceRemoved_removeUnsuitableDeviceLeavingOneSuitableDevice_shouldNotPausePlayback()
|
throws Exception {
|
||||||
throws Exception {
|
|
||||||
addWatchAsSystemFeature();
|
addWatchAsSystemFeature();
|
||||||
setupConnectedAudioOutput(
|
setupConnectedAudioOutput(
|
||||||
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
|
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
|
||||||
@ -13505,15 +13474,12 @@ public final class ExoPlayerTest {
|
|||||||
player.prepare();
|
player.prepare();
|
||||||
player.play();
|
player.play();
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
runUntilPlaybackState(player, Player.STATE_READY);
|
||||||
AtomicBoolean isPlaybackPaused = new AtomicBoolean(false);
|
List<Integer> playbackSuppressionList = new ArrayList<>();
|
||||||
player.addListener(
|
player.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(
|
public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) {
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
playbackSuppressionList.add(playbackSuppressionReason);
|
||||||
if (!playWhenReady) {
|
|
||||||
isPlaybackPaused.set(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -13522,13 +13488,18 @@ public final class ExoPlayerTest {
|
|||||||
player.stop();
|
player.stop();
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
runUntilPlaybackState(player, Player.STATE_IDLE);
|
||||||
|
|
||||||
assertThat(isPlaybackPaused.get()).isFalse();
|
assertThat(playbackSuppressionList).isEmpty();
|
||||||
player.release();
|
player.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests no change in the playback suppression reason when any suitable audio outputs has been
|
||||||
|
* removed during an ongoing playback but at least one suitable audio output is still connected to
|
||||||
|
* the device.
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
onAudioDeviceRemoved_removeSuitableDeviceLeavingOneSuitableDevice_shouldNotPausePlayback()
|
removeAnySuitableDeviceButOneSuitableDeviceStillConnected_shouldNotSetPlaybackSuppression()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
addWatchAsSystemFeature();
|
addWatchAsSystemFeature();
|
||||||
setupConnectedAudioOutput(
|
setupConnectedAudioOutput(
|
||||||
@ -13542,15 +13513,12 @@ public final class ExoPlayerTest {
|
|||||||
player.prepare();
|
player.prepare();
|
||||||
player.play();
|
player.play();
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
runUntilPlaybackState(player, Player.STATE_READY);
|
||||||
AtomicBoolean isPlaybackPaused = new AtomicBoolean(false);
|
List<Integer> playbackSuppressionList = new ArrayList<>();
|
||||||
player.addListener(
|
player.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(
|
public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) {
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
playbackSuppressionList.add(playbackSuppressionReason);
|
||||||
if (!playWhenReady) {
|
|
||||||
isPlaybackPaused.set(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -13558,40 +13526,7 @@ public final class ExoPlayerTest {
|
|||||||
player.stop();
|
player.stop();
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
runUntilPlaybackState(player, Player.STATE_IDLE);
|
||||||
|
|
||||||
assertThat(isPlaybackPaused.get()).isFalse();
|
assertThat(playbackSuppressionList).isEmpty();
|
||||||
player.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void
|
|
||||||
onAudioDeviceRemoved_removeSuitableDeviceOnNonWearSurface_shouldNotPauseOngoingPlayback()
|
|
||||||
throws Exception {
|
|
||||||
setupConnectedAudioOutput(
|
|
||||||
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
|
|
||||||
ExoPlayer player =
|
|
||||||
new TestExoPlayerBuilder(context).setSuppressPlaybackOnUnsuitableOutput(true).build();
|
|
||||||
player.setMediaItem(
|
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
|
||||||
player.prepare();
|
|
||||||
player.play();
|
|
||||||
runUntilPlaybackState(player, Player.STATE_READY);
|
|
||||||
AtomicBoolean isPlaybackPaused = new AtomicBoolean(false);
|
|
||||||
player.addListener(
|
|
||||||
new Player.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onPlayWhenReadyChanged(
|
|
||||||
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
|
||||||
if (!playWhenReady) {
|
|
||||||
isPlaybackPaused.set(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
removeConnectedAudioOutput(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
|
|
||||||
player.stop();
|
|
||||||
runUntilPlaybackState(player, Player.STATE_IDLE);
|
|
||||||
|
|
||||||
assertThat(isPlaybackPaused.get()).isFalse();
|
|
||||||
player.release();
|
player.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user