Commit 6c3a011d by krocard Committed by kim-vde

Listener for offload scheduling

Let the app know when offload scheduling is enabled or disabled.

PiperOrigin-RevId: 325790017
parent 9a0203e9
...@@ -611,7 +611,9 @@ public interface ExoPlayer extends Player { ...@@ -611,7 +611,9 @@ public interface ExoPlayer extends Player {
* *
* <p>While offload scheduling is enabled, player events may be delivered severely delayed and * <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 * apps should not interact with the player. When returning to the foreground, disable offload
* scheduling before interacting with the player * scheduling and wait for {@link
* Player.EventListener#onExperimentalOffloadSchedulingEnabled(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 * <p>This mode should save significant power when the phone is playing offload audio with the
* screen off. * screen off.
......
...@@ -1366,6 +1366,7 @@ import java.util.concurrent.TimeoutException; ...@@ -1366,6 +1366,7 @@ import java.util.concurrent.TimeoutException;
private final boolean playbackSuppressionReasonChanged; private final boolean playbackSuppressionReasonChanged;
private final boolean isPlayingChanged; private final boolean isPlayingChanged;
private final boolean playbackSpeedChanged; private final boolean playbackSpeedChanged;
private final boolean offloadSchedulingChanged;
public PlaybackInfoUpdate( public PlaybackInfoUpdate(
PlaybackInfo playbackInfo, PlaybackInfo playbackInfo,
...@@ -1404,6 +1405,8 @@ import java.util.concurrent.TimeoutException; ...@@ -1404,6 +1405,8 @@ import java.util.concurrent.TimeoutException;
previousPlaybackInfo.playbackSuppressionReason != playbackInfo.playbackSuppressionReason; previousPlaybackInfo.playbackSuppressionReason != playbackInfo.playbackSuppressionReason;
isPlayingChanged = isPlaying(previousPlaybackInfo) != isPlaying(playbackInfo); isPlayingChanged = isPlaying(previousPlaybackInfo) != isPlaying(playbackInfo);
playbackSpeedChanged = previousPlaybackInfo.playbackSpeed != playbackInfo.playbackSpeed; playbackSpeedChanged = previousPlaybackInfo.playbackSpeed != playbackInfo.playbackSpeed;
offloadSchedulingChanged =
previousPlaybackInfo.offloadSchedulingEnabled != playbackInfo.offloadSchedulingEnabled;
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
...@@ -1481,6 +1484,13 @@ import java.util.concurrent.TimeoutException; ...@@ -1481,6 +1484,13 @@ import java.util.concurrent.TimeoutException;
if (seekProcessed) { if (seekProcessed) {
invokeAll(listenerSnapshot, EventListener::onSeekProcessed); invokeAll(listenerSnapshot, EventListener::onSeekProcessed);
} }
if (offloadSchedulingChanged) {
invokeAll(
listenerSnapshot,
listener ->
listener.onExperimentalOffloadSchedulingEnabled(
playbackInfo.offloadSchedulingEnabled));
}
} }
private static boolean isPlaying(PlaybackInfo playbackInfo) { private static boolean isPlaying(PlaybackInfo playbackInfo) {
......
...@@ -937,6 +937,9 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -937,6 +937,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
throw new IllegalStateException("Playback stuck buffering and not loading"); throw new IllegalStateException("Playback stuck buffering and not loading");
} }
} }
if (offloadSchedulingEnabled != playbackInfo.offloadSchedulingEnabled) {
playbackInfo = playbackInfo.copyWithOffloadSchedulingEnabled(offloadSchedulingEnabled);
}
if ((shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY) if ((shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY)
|| playbackInfo.playbackState == Player.STATE_BUFFERING) { || playbackInfo.playbackState == Player.STATE_BUFFERING) {
...@@ -1284,7 +1287,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1284,7 +1287,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
playbackInfo.playbackSpeed, playbackInfo.playbackSpeed,
startPositionUs, startPositionUs,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
startPositionUs); startPositionUs,
offloadSchedulingEnabled);
if (releaseMediaSourceList) { if (releaseMediaSourceList) {
mediaSourceList.release(); mediaSourceList.release();
} }
......
...@@ -65,6 +65,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -65,6 +65,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
@PlaybackSuppressionReason public final int playbackSuppressionReason; @PlaybackSuppressionReason public final int playbackSuppressionReason;
/** The playback speed. */ /** The playback speed. */
public final float playbackSpeed; public final float playbackSpeed;
/** Whether the player is in offloadScheduling. */
public final boolean offloadSchedulingEnabled;
/** /**
* Position up to which media is buffered in {@link #loadingMediaPeriodId) relative to the start * Position up to which media is buffered in {@link #loadingMediaPeriodId) relative to the start
...@@ -106,7 +108,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -106,7 +108,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
Player.DEFAULT_PLAYBACK_SPEED, Player.DEFAULT_PLAYBACK_SPEED,
/* bufferedPositionUs= */ 0, /* bufferedPositionUs= */ 0,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
/* positionUs= */ 0); /* positionUs= */ 0,
/* offloadSchedulingEnabled= */ false);
} }
/** /**
...@@ -123,6 +126,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -123,6 +126,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
* @param bufferedPositionUs See {@link #bufferedPositionUs}. * @param bufferedPositionUs See {@link #bufferedPositionUs}.
* @param totalBufferedDurationUs See {@link #totalBufferedDurationUs}. * @param totalBufferedDurationUs See {@link #totalBufferedDurationUs}.
* @param positionUs See {@link #positionUs}. * @param positionUs See {@link #positionUs}.
* @param offloadSchedulingEnabled See {@link #offloadSchedulingEnabled}.
*/ */
public PlaybackInfo( public PlaybackInfo(
Timeline timeline, Timeline timeline,
...@@ -139,7 +143,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -139,7 +143,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
float playbackSpeed, float playbackSpeed,
long bufferedPositionUs, long bufferedPositionUs,
long totalBufferedDurationUs, long totalBufferedDurationUs,
long positionUs) { long positionUs,
boolean offloadSchedulingEnabled) {
this.timeline = timeline; this.timeline = timeline;
this.periodId = periodId; this.periodId = periodId;
this.requestedContentPositionUs = requestedContentPositionUs; this.requestedContentPositionUs = requestedContentPositionUs;
...@@ -155,6 +160,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -155,6 +160,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
this.bufferedPositionUs = bufferedPositionUs; this.bufferedPositionUs = bufferedPositionUs;
this.totalBufferedDurationUs = totalBufferedDurationUs; this.totalBufferedDurationUs = totalBufferedDurationUs;
this.positionUs = positionUs; this.positionUs = positionUs;
this.offloadSchedulingEnabled = offloadSchedulingEnabled;
} }
/** Returns a placeholder period id for an empty timeline. */ /** Returns a placeholder period id for an empty timeline. */
...@@ -198,7 +204,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -198,7 +204,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
} }
/** /**
...@@ -224,7 +231,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -224,7 +231,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
} }
/** /**
...@@ -250,7 +258,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -250,7 +258,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
} }
/** /**
...@@ -276,7 +285,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -276,7 +285,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
} }
/** /**
...@@ -302,7 +312,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -302,7 +312,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
} }
/** /**
...@@ -328,7 +339,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -328,7 +339,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
} }
/** /**
...@@ -358,7 +370,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -358,7 +370,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
} }
/** /**
...@@ -384,6 +397,35 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -384,6 +397,35 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
playbackSpeed, playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs,
offloadSchedulingEnabled);
}
/**
* Copies playback info with new offloadSchedulingEnabled.
*
* @param offloadSchedulingEnabled New offloadSchedulingEnabled state. See {@link
* #offloadSchedulingEnabled}.
* @return Copied playback info with new offload scheduling state.
*/
@CheckResult
public PlaybackInfo copyWithOffloadSchedulingEnabled(boolean offloadSchedulingEnabled) {
return new PlaybackInfo(
timeline,
periodId,
requestedContentPositionUs,
playbackState,
playbackError,
isLoading,
trackGroups,
trackSelectorResult,
loadingMediaPeriodId,
playWhenReady,
playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs,
totalBufferedDurationUs,
positionUs,
offloadSchedulingEnabled);
} }
} }
...@@ -604,6 +604,14 @@ public interface Player { ...@@ -604,6 +604,14 @@ public interface Player {
*/ */
@Deprecated @Deprecated
default void onSeekProcessed() {} default void onSeekProcessed() {}
/**
* Called when the player has started or stopped offload scheduling after a call to {@link
* ExoPlayer#experimentalEnableOffloadScheduling(boolean)}.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*/
default void onExperimentalOffloadSchedulingEnabled(boolean offloadSchedulingEnabled) {}
} }
/** /**
......
...@@ -438,7 +438,8 @@ public final class MediaPeriodQueueTest { ...@@ -438,7 +438,8 @@ public final class MediaPeriodQueueTest {
/* playbackSpeed= */ Player.DEFAULT_PLAYBACK_SPEED, /* playbackSpeed= */ Player.DEFAULT_PLAYBACK_SPEED,
/* bufferedPositionUs= */ 0, /* bufferedPositionUs= */ 0,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
/* positionUs= */ 0); /* positionUs= */ 0,
/* offloadSchedulingEnabled= */ false);
} }
private void advance() { private void advance() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment