You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
DefaultPreloadManager queue stalls on specifiedRangeCached items that are consumed before download completes #3458
Build a vertical-feed app with DefaultPreloadManager and TargetPreloadStatusControl returning PreloadStatus.specifiedRangeCached(0, 5000) for items at rank ≥ 1.
Register ~5 items with ranks 0..4 and call invalidate().
Immediately getMediaSource(itemAtRank1) and start playback on it (consume) before rank 0 reaches 100% download.
Expected result
The preload queue advances past the consumed/stalled item and starts preloading ranks 2, 3, 4.
Actual result
getTargetPreloadStatus(rankingData) is never called for ranks 2, 3, 4. The queue stays stuck on the earlier item whose PreCacheHelper download never reports 100%. Subsequent invalidate() calls do not help because the priority list restarts from the same stuck index.
Media
DefaultPreloadManager iterates its priority list strictly one source at a time: BasePreloadManager.invalidate() kicks off a single preload, and the queue advances to the next-ranked item only when onCompleted / onSkipped / onError fires on the currently preloading source.
For PreloadStatus.specifiedRangeLoaded(...), PreloadMediaSourceControl has three paths that advance the queue:
onContinueLoadingRequested → onCompleted once bufferedDurationUs >= durationMs
onLoadedToTheEndOfSource → onCompleted
onUsedByPlayer → onSkipped when the main player attaches to the preloaded MediaSource
For PreloadStatus.specifiedRangeCached(...), there is only one path:
There is no onUsedByPlayer equivalent for pre-cached items. On consume, onPrepared constructs a fresh MediaSource via preloadMediaSourceFactory.createMediaSource(updatedMediaItem) rather than attaching to the one being pre-cached, so the PreCacheHelper for the original MediaItem keeps running in the background and never reaches 100% in the user-visible timeline.
Result: when the user navigates past a specifiedRangeCached item before its download completes (common in short-form video / vertical feed UX), maybeAdvanceToNextMediaSourceHolder() is never called, and every lower-ranked source in the priority list stays unpreloaded indefinitely — even across subsequent invalidate() calls, since indexForSourceHolderToPreload is pinned to the stuck item.
Suggested fix
In DefaultPreloadManager hook PreloadMediaSource.PreloadControl.onUsedByPlayer(mediaSource) (or the matching PreCacheHelper lifecycle) to call onSkipped for the corresponding pre-cached MediaItem so the queue can advance. Alternatively, give PreCacheHelper an explicit "consumed/cancelled" terminal signal that DefaultPreloadManager can translate to onSkipped.
Activity
tonihei commentedon Oct 12, 2026
@tianyif Could you take a look?