Enable offload scheduling by default for audio-only offload playback

Removed `ExoPlayer.experimentalSetOffloadSchedulingEnabled` as scheduling will be enabled by default when offload is enabled for audio-only playback.

In addition, the `experimental` key word was taken out of the following
method signatures:
* `ExoPlayer.experimentalIsSleepingForOffload`
* `AudioOffloadListener.onExperimentalSleepingForOffloadChanged`
* `AudioOffloadListener.onExperimentalOffloadedPlayback`

PiperOrigin-RevId: 565035289
This commit is contained in:
michaelkatz 2023-09-13 06:44:33 -07:00 committed by Copybara-Service
parent abaf3e7aa1
commit 85c944b955
9 changed files with 197 additions and 127 deletions

View File

@ -35,6 +35,12 @@
* Add support for Opus gapless metadata during offload playback.
* Allow renderer recovery by disabling offload if failed at first write
([#627](https://github.com/androidx/media/issues/627)).
* Enable Offload Scheduling by default for audio-only offloaded playback.
* Delete `ExoPlayer.experimentalSetOffloadSchedulingEnabled` and
`AudioOffloadListener.onExperimentalOffloadSchedulingEnabledChanged`.
* Renamed `onExperimentalSleepingForOffloadChanged` as
`onSleepingForOffloadChanged` and `onExperimentalOffloadedPlayback` as
`onOffloadedPlayback`.
* Video:
* Text:
* Metadata:

View File

@ -421,37 +421,24 @@ public interface ExoPlayer extends Player {
void setDeviceMuted(boolean muted);
}
/**
* A listener for audio offload events.
*
* <p>This class is experimental, and might be renamed, moved or removed in a future release.
*/
/** A listener for audio offload events. */
@UnstableApi
interface AudioOffloadListener {
/**
* Called when the player has started or stopped offload scheduling using {@link
* #experimentalSetOffloadSchedulingEnabled(boolean)}.
* Called when the value of {@link #isSleepingForOffload} changes.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
* <p>When {@code isSleepingForOffload} is {@code true} then, the player has paused its main
* loop to save power in offload scheduling mode.
*/
default void onExperimentalOffloadSchedulingEnabledChanged(boolean offloadSchedulingEnabled) {}
/**
* Called when the player has started or finished sleeping for offload.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*/
default void onExperimentalSleepingForOffloadChanged(boolean sleepingForOffload) {}
default void onSleepingForOffloadChanged(boolean isSleepingForOffload) {}
/**
* Called when the value of {@link AudioTrack#isOffloadedPlayback} changes.
*
* <p>This should not be generally required to be acted upon. But when offload is critical for
* efficiency, or audio features (gapless, playback speed), this will let the app know.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*/
default void onExperimentalOffloadedPlayback(boolean offloadedPlayback) {}
default void onOffloadedPlayback(boolean isOffloadedPlayback) {}
}
/**
@ -1827,24 +1814,13 @@ public interface ExoPlayer extends Player {
void setPriorityTaskManager(@Nullable PriorityTaskManager priorityTaskManager);
/**
* Sets whether audio offload scheduling is enabled. If enabled, ExoPlayer's main loop will run as
* rarely as possible when playing an audio stream using audio offload.
* Returns whether the player has paused its main loop to save power in offload scheduling mode.
*
* <p>Only use this scheduling mode if the player is not displaying anything to the user. For
* example when the application is in the background, or the screen is off. The player state
* (including position) is rarely updated (roughly between every 10 seconds and 1 minute).
* <p>Offload scheduling mode should save significant power when the phone is playing offload
* audio with the screen off.
*
* <p>While offload scheduling is enabled, player events may be delivered severely delayed and
* apps should not interact with the player. When returning to the foreground, disable offload
* scheduling and wait for {@link
* AudioOffloadListener#onExperimentalOffloadSchedulingEnabledChanged(boolean)} to be called with
* {@code offloadSchedulingEnabled = false} before interacting with the player.
*
* <p>This mode should save significant power when the phone is playing offload audio with the
* screen off.
*
* <p>This mode only has an effect when playing an audio track in offload mode, which requires all
* the following:
* <p>Offload scheduling is only enabled when playing an audio track in offload mode, which
* requires all the following:
*
* <ul>
* <li>Audio offload rendering is enabled through {@link
@ -1854,24 +1830,10 @@ public interface ExoPlayer extends Player {
* <li>The {@link AudioSink} is playing with an offload {@link AudioTrack}.
* </ul>
*
* <p>The state where ExoPlayer main loop has been paused to save power during offload playback
* can be queried with {@link #experimentalIsSleepingForOffload()}.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*
* @param offloadSchedulingEnabled Whether to enable offload scheduling.
* @see AudioOffloadListener#onSleepingForOffloadChanged(boolean)
*/
@UnstableApi
void experimentalSetOffloadSchedulingEnabled(boolean offloadSchedulingEnabled);
/**
* Returns whether the player has paused its main loop to save power in offload scheduling mode.
*
* @see #experimentalSetOffloadSchedulingEnabled(boolean)
* @see AudioOffloadListener#onExperimentalSleepingForOffloadChanged(boolean)
*/
@UnstableApi
boolean experimentalIsSleepingForOffload();
boolean isSleepingForOffload();
/**
* Returns whether <a

View File

@ -466,16 +466,7 @@ import java.util.concurrent.TimeoutException;
}
@Override
public void experimentalSetOffloadSchedulingEnabled(boolean offloadSchedulingEnabled) {
verifyApplicationThread();
internalPlayer.experimentalSetOffloadSchedulingEnabled(offloadSchedulingEnabled);
for (AudioOffloadListener listener : audioOffloadListeners) {
listener.onExperimentalOffloadSchedulingEnabledChanged(offloadSchedulingEnabled);
}
}
@Override
public boolean experimentalIsSleepingForOffload() {
public boolean isSleepingForOffload() {
verifyApplicationThread();
return playbackInfo.sleepingForOffload;
}
@ -2135,7 +2126,7 @@ import java.util.concurrent.TimeoutException;
if (previousPlaybackInfo.sleepingForOffload != newPlaybackInfo.sleepingForOffload) {
for (AudioOffloadListener listener : audioOffloadListeners) {
listener.onExperimentalSleepingForOffloadChanged(newPlaybackInfo.sleepingForOffload);
listener.onSleepingForOffloadChanged(newPlaybackInfo.sleepingForOffload);
}
}
}
@ -2817,7 +2808,7 @@ import java.util.concurrent.TimeoutException;
switch (playbackState) {
case Player.STATE_READY:
case Player.STATE_BUFFERING:
boolean isSleeping = experimentalIsSleepingForOffload();
boolean isSleeping = isSleepingForOffload();
wakeLockManager.setStayAwake(getPlayWhenReady() && !isSleeping);
// The wifi lock is not released while sleeping to avoid interrupting downloads.
wifiLockManager.setStayAwake(getPlayWhenReady());
@ -3262,7 +3253,7 @@ import java.util.concurrent.TimeoutException;
// Player.AudioOffloadListener implementation.
@Override
public void onExperimentalSleepingForOffloadChanged(boolean sleepingForOffload) {
public void onSleepingForOffloadChanged(boolean sleepingForOffload) {
updateWakeAndWifiLock();
}
}

View File

@ -18,6 +18,7 @@ package androidx.media3.exoplayer;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.castNonNull;
import static androidx.media3.common.util.Util.msToUs;
import static androidx.media3.exoplayer.audio.AudioSink.OFFLOAD_MODE_DISABLED;
import static java.lang.Math.max;
import static java.lang.Math.min;
@ -164,7 +165,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
private static final int MSG_SET_SHUFFLE_ORDER = 21;
private static final int MSG_PLAYLIST_UPDATE_REQUESTED = 22;
private static final int MSG_SET_PAUSE_AT_END_OF_WINDOW = 23;
private static final int MSG_SET_OFFLOAD_SCHEDULING_ENABLED = 24;
private static final int MSG_ATTEMPT_RENDERER_ERROR_RECOVERY = 25;
private static final int MSG_RENDERER_CAPABILITIES_CHANGED = 26;
private static final int MSG_UPDATE_MEDIA_SOURCES_WITH_MEDIA_ITEMS = 27;
@ -317,13 +317,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
this.setForegroundModeTimeoutMs = setForegroundModeTimeoutMs;
}
public void experimentalSetOffloadSchedulingEnabled(boolean offloadSchedulingEnabled) {
handler
.obtainMessage(
MSG_SET_OFFLOAD_SCHEDULING_ENABLED, offloadSchedulingEnabled ? 1 : 0, /* unused */ 0)
.sendToTarget();
}
public void prepare() {
handler.obtainMessage(MSG_PREPARE).sendToTarget();
}
@ -590,9 +583,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
case MSG_SET_PAUSE_AT_END_OF_WINDOW:
setPauseAtEndOfWindowInternal(msg.arg1 != 0);
break;
case MSG_SET_OFFLOAD_SCHEDULING_ENABLED:
setOffloadSchedulingEnabledInternal(msg.arg1 == 1);
break;
case MSG_ATTEMPT_RENDERER_ERROR_RECOVERY:
attemptRendererErrorRecovery();
break;
@ -891,7 +881,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
private void setOffloadSchedulingEnabledInternal(boolean offloadSchedulingEnabled) {
private void setOffloadSchedulingEnabled(boolean offloadSchedulingEnabled) {
if (offloadSchedulingEnabled == this.offloadSchedulingEnabled) {
return;
}
@ -2301,6 +2291,30 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
private void maybeUpdateOffloadScheduling() {
// If playing period is audio-only with offload mode preference to enable, then offload
// scheduling should be enabled.
@Nullable MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
if (playingPeriodHolder != null) {
TrackSelectorResult trackSelectorResult = playingPeriodHolder.getTrackSelectorResult();
boolean isAudioRendererEnabledAndOffloadPreferred = false;
boolean isAudioOnly = true;
for (int i = 0; i < renderers.length; i++) {
if (trackSelectorResult.isRendererEnabled(i)) {
if (renderers[i].getTrackType() != C.TRACK_TYPE_AUDIO) {
isAudioOnly = false;
break;
}
if (trackSelectorResult.rendererConfigurations[i].offloadModePreferred
!= OFFLOAD_MODE_DISABLED) {
isAudioRendererEnabledAndOffloadPreferred = true;
}
}
}
setOffloadSchedulingEnabled(isAudioRendererEnabledAndOffloadPreferred && isAudioOnly);
}
}
private void allowRenderersToRenderStartOfStreams() {
TrackSelectorResult playingTracks = queue.getPlayingPeriod().getTrackSelectorResult();
for (int i = 0; i < renderers.length; i++) {
@ -2546,6 +2560,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
playingPeriodHolder.info =
playingPeriodHolder.info.copyWithRequestedContentPositionUs(requestedContentPositionUs);
}
maybeUpdateOffloadScheduling();
} else if (!mediaPeriodId.equals(playbackInfo.periodId)) {
// Reset previously kept track info if unprepared and the period changes.
trackGroupArray = TrackGroupArray.EMPTY;

View File

@ -446,15 +446,9 @@ public class SimpleExoPlayer extends BasePlayer
}
@Override
public void experimentalSetOffloadSchedulingEnabled(boolean offloadSchedulingEnabled) {
public boolean isSleepingForOffload() {
blockUntilConstructorFinished();
player.experimentalSetOffloadSchedulingEnabled(offloadSchedulingEnabled);
}
@Override
public boolean experimentalIsSleepingForOffload() {
blockUntilConstructorFinished();
return player.experimentalIsSleepingForOffload();
return player.isSleepingForOffload();
}
/**

View File

@ -1024,7 +1024,7 @@ public final class DefaultAudioSink implements AudioSink {
AudioTrack audioTrack =
configuration.buildAudioTrack(tunneling, audioAttributes, audioSessionId);
if (audioOffloadListener != null) {
audioOffloadListener.onExperimentalOffloadedPlayback(isOffloadedPlayback(audioTrack));
audioOffloadListener.onOffloadedPlayback(isOffloadedPlayback(audioTrack));
}
return audioTrack;
} catch (InitializationException e) {

View File

@ -121,6 +121,7 @@ import androidx.media3.common.Player.PositionInfo;
import androidx.media3.common.Timeline;
import androidx.media3.common.Timeline.Window;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.Tracks;
import androidx.media3.common.VideoSize;
import androidx.media3.common.util.Assertions;
@ -10198,53 +10199,118 @@ public final class ExoPlayerTest {
}
@Test
public void enableOffloadScheduling_isReported() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
ExoPlayer.AudioOffloadListener mockListener = mock(ExoPlayer.AudioOffloadListener.class);
player.addAudioOffloadListener(mockListener);
player.experimentalSetOffloadSchedulingEnabled(true);
verify(mockListener).onExperimentalOffloadSchedulingEnabledChanged(true);
player.experimentalSetOffloadSchedulingEnabled(false);
verify(mockListener).onExperimentalOffloadSchedulingEnabledChanged(false);
}
@Test
public void enableOffloadScheduling_isEnable_playerSleeps() throws Exception {
public void enablingOffload_withAudioOnly_playerSleeps() throws Exception {
FakeSleepRenderer sleepRenderer = new FakeSleepRenderer(C.TRACK_TYPE_AUDIO);
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(sleepRenderer).build();
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.experimentalSetOffloadSchedulingEnabled(true);
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
player.prepare();
player.play();
sleepRenderer.sleepOnNextRender();
runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ true);
assertThat(player.experimentalIsSleepingForOffload()).isTrue();
assertThat(player.isSleepingForOffload()).isTrue();
player.release();
}
@Test
public void
experimentalEnableOffloadSchedulingWhileSleepingForOffload_isDisabled_renderingResumes()
throws Exception {
public void enablingOffloadDuringPlayback_withAudioOnly_playerSleeps() throws Exception {
FakeSleepRenderer sleepRenderer = new FakeSleepRenderer(C.TRACK_TYPE_AUDIO);
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(sleepRenderer).build();
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.prepare();
player.play();
runUntilPlaybackState(player, Player.STATE_READY);
sleepRenderer.sleepOnNextRender();
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ true);
assertThat(player.isSleepingForOffload()).isTrue();
player.release();
}
@Test
public void enableOffloadScheduling_whenPlayerSleeps_callsOnSleepingForOffloadChanged()
throws Exception {
FakeSleepRenderer sleepRenderer = new FakeSleepRenderer(C.TRACK_TYPE_AUDIO);
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(sleepRenderer).build();
ExoPlayer.AudioOffloadListener mockListener = mock(ExoPlayer.AudioOffloadListener.class);
player.addAudioOffloadListener(mockListener);
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
player.prepare();
player.play();
sleepRenderer.sleepOnNextRender();
runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ true);
verify(mockListener).onSleepingForOffloadChanged(true);
player.release();
}
@Test
public void enableOffloadScheduling_whenOffloadIsDisabled_renderingResumes() throws Exception {
FakeSleepRenderer sleepRenderer = new FakeSleepRenderer(C.TRACK_TYPE_AUDIO).sleepOnNextRender();
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(sleepRenderer).build();
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.experimentalSetOffloadSchedulingEnabled(true);
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
player.prepare();
player.play();
runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ true);
player.experimentalSetOffloadSchedulingEnabled(false); // Force the player to exit offload sleep
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ false);
assertThat(player.experimentalIsSleepingForOffload()).isFalse();
assertThat(player.isSleepingForOffload()).isFalse();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
@ -10256,22 +10322,29 @@ public final class ExoPlayerTest {
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(sleepRenderer).build();
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.experimentalSetOffloadSchedulingEnabled(true);
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
player.prepare();
player.play();
runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ true);
sleepRenderer.wakeup();
runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ false);
assertThat(player.experimentalIsSleepingForOffload()).isFalse();
runUntilPlaybackState(player, Player.STATE_ENDED);
assertThat(player.isSleepingForOffload()).isFalse();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
}
@Test
public void enableOffloadScheduling_duringSleepGetCurrentPosition_returnsEstimatedPosition()
public void enableOffload_duringSleepGetCurrentPosition_returnsEstimatedPosition()
throws Exception {
FakeClock fakeClock =
new FakeClock(/* initialTimeMs= */ 987_654_321L, /* isAutoAdvancing= */ true);
@ -10280,7 +10353,15 @@ public final class ExoPlayerTest {
new TestExoPlayerBuilder(context).setClock(fakeClock).setRenderers(sleepRenderer).build();
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.experimentalSetOffloadSchedulingEnabled(true);
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
player.prepare();
player.play();
sleepRenderer.sleepOnNextRender();
@ -10297,7 +10378,7 @@ public final class ExoPlayerTest {
}
@Test
public void enableOffloadScheduling_pauseAndSeekDuringSleep_currentPositionIsSeekedPosition()
public void enableOffload_pauseAndSeekDuringSleep_currentPositionIsSeekedPosition()
throws Exception {
FakeClock fakeClock =
new FakeClock(/* initialTimeMs= */ 987_654_321L, /* isAutoAdvancing= */ true);
@ -10306,7 +10387,15 @@ public final class ExoPlayerTest {
new TestExoPlayerBuilder(context).setClock(fakeClock).setRenderers(sleepRenderer).build();
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.experimentalSetOffloadSchedulingEnabled(true);
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
player.prepare();
player.play();
sleepRenderer.sleepOnNextRender();
@ -10324,7 +10413,7 @@ public final class ExoPlayerTest {
}
@Test
public void enableOffloadScheduling_seekThenPauseDuringSleep_returnsEstimatePositionByPauseTime()
public void enableOffload_seekThenPauseDuringSleep_returnsEstimatePositionByPauseTime()
throws Exception {
FakeClock fakeClock =
new FakeClock(/* initialTimeMs= */ 987_654_321L, /* isAutoAdvancing= */ true);
@ -10333,7 +10422,15 @@ public final class ExoPlayerTest {
new TestExoPlayerBuilder(context).setClock(fakeClock).setRenderers(sleepRenderer).build();
Timeline timeline = new FakeTimeline();
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.AUDIO_FORMAT));
player.experimentalSetOffloadSchedulingEnabled(true);
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setAudioOffloadPreference(
TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED,
/* isGaplessSupportRequired= */ false,
/* isSpeedChangeSupportRequired= */ false)
.build());
player.prepare();
player.play();
sleepRenderer.sleepOnNextRender();
@ -14098,6 +14195,16 @@ public final class ExoPlayerTest {
return this;
}
@Override
public @Capabilities int supportsFormat(Format format) throws ExoPlaybackException {
@Capabilities int rendererCapabilities = super.supportsFormat(format);
if (RendererCapabilities.getFormatSupport(rendererCapabilities) == C.FORMAT_HANDLED
&& getTrackType() == C.TRACK_TYPE_AUDIO) {
rendererCapabilities |= AUDIO_OFFLOAD_SUPPORTED;
}
return rendererCapabilities;
}
@Override
public void handleMessage(@MessageType int messageType, @Nullable Object message)
throws ExoPlaybackException {

View File

@ -398,12 +398,7 @@ public class StubExoPlayer extends StubPlayer implements ExoPlayer {
}
@Override
public void experimentalSetOffloadSchedulingEnabled(boolean offloadSchedulingEnabled) {
throw new UnsupportedOperationException();
}
@Override
public boolean experimentalIsSleepingForOffload() {
public boolean isSleepingForOffload() {
throw new UnsupportedOperationException();
}

View File

@ -225,8 +225,8 @@ public class TestPlayerRunHelper {
/**
* Runs tasks of the main {@link Looper} until {@link
* ExoPlayer.AudioOffloadListener#onExperimentalSleepingForOffloadChanged(boolean)} is called or a
* playback error occurs.
* ExoPlayer.AudioOffloadListener#onSleepingForOffloadChanged(boolean)} is called or a playback
* error occurs.
*
* <p>If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
@ -244,7 +244,7 @@ public class TestPlayerRunHelper {
ExoPlayer.AudioOffloadListener listener =
new ExoPlayer.AudioOffloadListener() {
@Override
public void onExperimentalSleepingForOffloadChanged(boolean sleepingForOffload) {
public void onSleepingForOffloadChanged(boolean sleepingForOffload) {
if (sleepingForOffload == expectedSleepForOffload) {
receiverCallback.set(true);
}