Commit 036a28b2 by christosts Committed by tonihei

MediaController: stop advancing content position when player is paused

MediaController.getContentPosition() estimates the content position
based on the last position info sent by the player and the elapsed
real-time since the position info was received. After calling
MediaController's play/pause/setPlayWhenReady, the position estimation
logic is still applying, therefore advancing the position until the
underlying player's actual position is received. This can make the
MediaController's content position to be out of sync with player's
actual content position.

With this change, MediaController stops making content position
estimations after any of play/pause/setPlayWhenReady is called and
until a new position info is received from the underlying player.

Tested manually with the the session demo app, pausing/resuming content
from the UI.

PiperOrigin-RevId: 418000800
parent a9660de1
......@@ -186,6 +186,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
private int surfaceWidth;
private int surfaceHeight;
@Nullable private IMediaSession iSession;
private long lastReturnedContentPositionMs;
private long lastSetPlayWhenReadyCalledTimeMs;
public MediaControllerImplBase(
Context context, MediaController instance, SessionToken token, Bundle connectionHints) {
......@@ -228,6 +230,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
this.instance.runOnApplicationLooper(MediaControllerImplBase.this.instance::release);
}
flushCommandQueueHandler = new FlushCommandQueueHandler(instance.getApplicationLooper());
lastReturnedContentPositionMs = C.TIME_UNSET;
lastSetPlayWhenReadyCalledTimeMs = C.TIME_UNSET;
}
@Override
......@@ -662,9 +666,22 @@ import org.checkerframework.checker.nullness.qual.NonNull;
@Override
public long getContentPosition() {
boolean receivedUpdatedPositionInfo =
lastSetPlayWhenReadyCalledTimeMs != C.TIME_UNSET
&& lastSetPlayWhenReadyCalledTimeMs < playerInfo.sessionPositionInfo.eventTimeMs;
if (!playerInfo.isPlaying || playerInfo.sessionPositionInfo.isPlayingAd) {
return playerInfo.sessionPositionInfo.positionInfo.contentPositionMs;
if (receivedUpdatedPositionInfo || lastReturnedContentPositionMs == C.TIME_UNSET) {
lastReturnedContentPositionMs =
playerInfo.sessionPositionInfo.positionInfo.contentPositionMs;
}
return lastReturnedContentPositionMs;
}
if (!receivedUpdatedPositionInfo && lastReturnedContentPositionMs != C.TIME_UNSET) {
// We need an updated content position to make a new position estimation.
return lastReturnedContentPositionMs;
}
long elapsedTimeMs =
(instance.getTimeDiffMs() != C.TIME_UNSET)
? instance.getTimeDiffMs()
......@@ -672,9 +689,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
long estimatedPositionMs =
playerInfo.sessionPositionInfo.positionInfo.contentPositionMs
+ (long) (elapsedTimeMs * playerInfo.playbackParameters.speed);
return playerInfo.sessionPositionInfo.contentDurationMs == C.TIME_UNSET
? estimatedPositionMs
: Math.min(estimatedPositionMs, playerInfo.sessionPositionInfo.contentDurationMs);
if (playerInfo.sessionPositionInfo.contentDurationMs != C.TIME_UNSET) {
estimatedPositionMs =
Math.min(estimatedPositionMs, playerInfo.sessionPositionInfo.contentDurationMs);
}
lastReturnedContentPositionMs = estimatedPositionMs;
return lastReturnedContentPositionMs;
}
@Override
......@@ -2051,6 +2071,9 @@ import org.checkerframework.checker.nullness.qual.NonNull;
&& playerInfo.playbackSuppressionReason == playbackSuppressionReason) {
return;
}
// Stop estimating content position until a new positionInfo arrives from the player
lastSetPlayWhenReadyCalledTimeMs = SystemClock.elapsedRealtime();
PlayerInfo playerInfo =
this.playerInfo.copyWithPlayWhenReady(
playWhenReady, playWhenReadyChangeReason, playbackSuppressionReason);
......
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