From 3488c047e87c881994ae37f78ee4701cadcfcf1c Mon Sep 17 00:00:00 2001 From: olly Date: Fri, 23 Jul 2021 15:43:05 +0100 Subject: [PATCH] Refine LoadErrorHandlingPolicy Javadoc PiperOrigin-RevId: 386453305 --- .../DefaultLoadErrorHandlingPolicy.java | 47 +++++----- .../upstream/LoadErrorHandlingPolicy.java | 89 ++++++++++--------- 2 files changed, 67 insertions(+), 69 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java index ff8e60ff5c..8544a294a8 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java @@ -69,24 +69,24 @@ public class DefaultLoadErrorHandlingPolicy implements LoadErrorHandlingPolicy { } /** - * Returns the fallback selection. + * Returns whether a loader should fall back to using another resource on encountering an error, + * and if so the duration for which the failing resource should be excluded. * - *

The exclusion duration is given by {@link #DEFAULT_TRACK_EXCLUSION_MS} or {@link - * #DEFAULT_LOCATION_EXCLUSION_MS} if the load error was not an {@link - * #isRecoverableError(IOException) recoverable error}. In case of a recoverable error null is - * returned to disable exclusion but retry the same load instead. - * - *

If alternative locations {@link - * LoadErrorHandlingPolicy.FallbackOptions#isFallbackAvailable(int) are advertised}, {@link - * #FALLBACK_TYPE_LOCATION} is selected until all locations are excluded, {@link - * #FALLBACK_TYPE_TRACK} otherwise. + *

*/ @Override @Nullable public FallbackSelection getFallbackSelectionFor( FallbackOptions fallbackOptions, LoadErrorInfo loadErrorInfo) { - if (isRecoverableError(loadErrorInfo.exception)) { - // Don't fallback. Retry the same load again. + if (!isEligibleForFallback(loadErrorInfo.exception)) { return null; } // Prefer location fallbacks to track fallbacks, when both are available. @@ -130,23 +130,18 @@ public class DefaultLoadErrorHandlingPolicy implements LoadErrorHandlingPolicy { } } - /** - * Returns whether the error is considered recoverable. - * - * @param exception The exception. - * @return Whether the error is considered an recoverable error. - */ - protected boolean isRecoverableError(IOException exception) { + /** Returns whether an error should trigger a fallback if possible. */ + protected boolean isEligibleForFallback(IOException exception) { if (!(exception instanceof InvalidResponseCodeException)) { - return true; + return false; } InvalidResponseCodeException invalidResponseCodeException = (InvalidResponseCodeException) exception; - return invalidResponseCodeException.responseCode != 403 // HTTP 403 Forbidden. - && invalidResponseCodeException.responseCode != 404 // HTTP 404 Not Found. - && invalidResponseCodeException.responseCode != 410 // HTTP 410 Gone. - && invalidResponseCodeException.responseCode != 416 // HTTP 416 Range Not Satisfiable. - && invalidResponseCodeException.responseCode != 500 // HTTP 500 Internal Server Error. - && invalidResponseCodeException.responseCode != 503; // HTTP 503 Service Unavailable. + return invalidResponseCodeException.responseCode == 403 // HTTP 403 Forbidden. + || invalidResponseCodeException.responseCode == 404 // HTTP 404 Not Found. + || invalidResponseCodeException.responseCode == 410 // HTTP 410 Gone. + || invalidResponseCodeException.responseCode == 416 // HTTP 416 Range Not Satisfiable. + || invalidResponseCodeException.responseCode == 500 // HTTP 500 Internal Server Error. + || invalidResponseCodeException.responseCode == 503; // HTTP 503 Service Unavailable. } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java index 6ab21f5528..0815f9ed5f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java @@ -30,18 +30,20 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Defines how errors encountered by loaders are handled. + * A policy that defines how load errors are handled. * - *

A loader that can choose between one of a number of resources can exclude a resource when a - * load error occurs. In this case, {@link #getFallbackSelectionFor(FallbackOptions, LoadErrorInfo)} - * defines whether the resource should be excluded for a given {@link FallbackType fallback type}, - * and if so for how long. If the policy indicates that a resource should be excluded, the loader - * will exclude it for the specified amount of time unless all of the alternatives for the given - * fallback type are already excluded. + *

Some loaders are able to choose between a number of alternate resources. Such loaders will + * call {@link #getFallbackSelectionFor(FallbackOptions, LoadErrorInfo)} when a load error occurs. + * The {@link FallbackSelection} returned by the policy defines whether the loader should fall back + * to using another resource, and if so the duration for which the failing resource should be + * excluded. * - *

When exclusion does not take place, {@link #getRetryDelayMsFor(LoadErrorInfo)} defines whether - * the load is retried. An error that's not retried will always be propagated. An error that is - * retried will be propagated according to {@link #getMinimumLoadableRetryCount(int)}. + *

When fallback does not take place, a loader will call {@link + * #getRetryDelayMsFor(LoadErrorInfo)}. The value returned by the policy defines whether the failed + * load can be retried, and if so the duration to wait before retrying. If the policy indicates that + * a load error should not be retried, it will be considered fatal by the loader. The loader may + * also consider load errors that can be retried fatal if at least {@link + * #getMinimumLoadableRetryCount(int)} retries have been attempted. * *

Methods are invoked on the playback thread. */ @@ -54,14 +56,13 @@ public interface LoadErrorHandlingPolicy { @interface FallbackType {} /** - * Fallback type that is using exclusion of locations (i.e., multiple URLs through which the same - * data is accessible). + * Fallback to the same resource at a different location (i.e., a different URL through which the + * exact same data can be requested). */ int FALLBACK_TYPE_LOCATION = 1; /** - * Fallback type that is using exclusion of tracks (i.e., multiple URLs through which different - * representations of the same content are available; for example the same video encoded at - * different bitrates or resolutions). + * Fallback to a different track (i.e., a different representation of the same content; for + * example the same video encoded at a different bitrate or resolution). */ int FALLBACK_TYPE_TRACK = 2; @@ -92,16 +93,16 @@ public interface LoadErrorHandlingPolicy { /** Holds information about the available fallback options. */ final class FallbackOptions { - /** The number of total available alternative locations. */ + /** The number of available locations. */ public final int numberOfLocations; /** The number of locations that are already excluded. */ public final int numberOfExcludedLocations; - /** The number of total available tracks. */ + /** The number of tracks. */ public final int numberOfTracks; /** The number of tracks that are already excluded. */ public final int numberOfExcludedTracks; - /** Creates an instance with the given values. */ + /** Creates an instance. */ public FallbackOptions( int numberOfLocations, int numberOfExcludedLocations, @@ -121,16 +122,19 @@ public interface LoadErrorHandlingPolicy { } } - /** The selection of a fallback option determining the fallback behaviour on load error. */ + /** A selected fallback option. */ final class FallbackSelection { - /** The {@link FallbackType fallback type} to use. */ + /** The type of fallback. */ @FallbackType public final int type; - /** The exclusion duration of the {@link #type}, in milliseconds. */ + /** The duration for which the failing resource should be excluded, in milliseconds. */ public final long exclusionDurationMs; /** - * Creates an instance with the given values. The exclusion duration, in milliseconds, needs to - * be a positive integer. + * Creates an instance. + * + * @param type The type of fallback. + * @param exclusionDurationMs The duration for which the failing resource should be excluded, in + * milliseconds. Must be non-negative. */ public FallbackSelection(@FallbackType int type, long exclusionDurationMs) { checkArgument(exclusionDurationMs >= 0); @@ -140,33 +144,32 @@ public interface LoadErrorHandlingPolicy { } /** - * Returns the {@link FallbackSelection fallback selection} that determines the exclusion - * behaviour on load error. If null is returned the caller will disable exclusion. + * Returns whether a loader should fall back to using another resource on encountering an error, + * and if so the duration for which the failing resource should be excluded. * - *

If {@link FallbackSelection#type} is of a type that is not {@link - * FallbackOptions#isFallbackAvailable(int) advertised as available}, then the caller will disable - * exclusion as if null had been returned. + *

If the returned {@link FallbackSelection#type fallback type} was not {@link + * FallbackOptions#isFallbackAvailable(int) advertised as available}, then the loader will not + * fall back. * * @param fallbackOptions The available fallback options. * @param loadErrorInfo A {@link LoadErrorInfo} holding information about the load error. - * @return The fallback selection indicating which exclusion type to apply and for how long the - * resource should be excluded. Returning null indicates to disable exclusion. + * @return The selected fallback, or {@code null} if the calling loader should not fall back. */ @Nullable FallbackSelection getFallbackSelectionFor( FallbackOptions fallbackOptions, LoadErrorInfo loadErrorInfo); /** - * Returns the number of milliseconds to wait before attempting the load again, or {@link - * C#TIME_UNSET} if the error is fatal and should not be retried. + * Returns whether a loader can retry on encountering an error, and if so the duration to wait + * before retrying. A return value of {@link C#TIME_UNSET} indicates that the error is fatal and + * should not be retried. * - *

Loaders may ignore the retry delay returned by this method in order to wait for a specific - * event before retrying. However, the load is retried if and only if this method does not return - * {@link C#TIME_UNSET}. + *

For loads that can be retried, loaders may ignore the retry delay returned by this method in + * order to wait for a specific event before retrying. * * @param loadErrorInfo A {@link LoadErrorInfo} holding information about the load error. - * @return The number of milliseconds to wait before attempting the load again, or {@link - * C#TIME_UNSET} if the error is fatal and should not be retried. + * @return The duration to wait before retrying in milliseconds, or {@link C#TIME_UNSET} if the + * error is fatal and should not be retried. */ long getRetryDelayMsFor(LoadErrorInfo loadErrorInfo); @@ -179,13 +182,13 @@ public interface LoadErrorHandlingPolicy { default void onLoadTaskConcluded(long loadTaskId) {} /** - * Returns the minimum number of times to retry a load in the case of a load error, before - * propagating the error. + * Returns the minimum number of times to retry a load before a load error that can be retried may + * be considered fatal. * - * @param dataType One of the {@link C C.DATA_TYPE_*} constants indicating the type of data to - * load. - * @return The minimum number of times to retry a load in the case of a load error, before - * propagating the error. + * @param dataType One of the {@link C C.DATA_TYPE_*} constants indicating the type of data being + * loaded. + * @return The minimum number of times to retry a load before a load error that can be retried may + * be considered fatal. * @see Loader#startLoading(Loadable, Callback, int) */ int getMinimumLoadableRetryCount(int dataType);