@UnstableApi
public final class Flags


Central registry for Media3 experimental feature flags.

This class provides a mechanism to control experimental features in Media3 via global canary mode and individual flag overrides, enabling safe, gradual rollout of new library behaviors.

Canary mode

Canary mode is enabled by default. Only flags that are considered safe for production usage are included in canary mode. When canary mode is disabled, these flags are inactive.

Individual overrides

Individual flags can be explicitly enabled or disabled, regardless of the canary mode state. An explicit override always takes precedence over the canary mode default.

Threading

Flag configuration must be done on the application thread before creating any Media3 components (e.g., ExoPlayer, Transformer). Flag queries from other threads (e.g., the playback thread) rely on happens-before relationships established by start and android.os.Handler message posting during component setup.

Testing

In unit tests, androidx.media3.test.utils.Media3FlagsRule is the preferred way to manage flag states and automatically reset all flag overrides and canary mode after each test.

Summary

Nested types

@Documented
@Retention(value = RetentionPolicy.SOURCE)
@Target(value = ElementType.TYPE_USE)
@IntDef(open = true, value = )
public annotation Flags.Flag

Flags for experimental features in Media3.

Constants

static final int

Flag to enable dynamic scheduling in ExoPlayer.

static final int

Flag to enable delegating end-position clipping to MediaPeriod instances in ExoPlayer.

static final int

Flag to enable passing BUFFER_FLAG_DECODE_ONLY to android.media.MediaCodec on API 34+.

static final int

Flag to enable stuck playing detection in ExoPlayer.

static final int

Flag to enable enforcing that read and peek methods in ParsableByteArray do not read beyond limit.

static final int

Flag to enable parsing DASH Alternative MPD events into Period.alternativeMpdEvents in DashManifestParser.

static final int

Flag to enable per-stream media progression in ExoPlayer.

static final int

Flag to enable calling play and pause immediately after creating an android.media.AudioTrack.

static final int

Flag to enable invoking MediaCodecRenderer.onProcessedStreamChange() on the first stream.

static final int

Flag to skip calling flush before release on API 29+.

static final int

Flag to enable calculating duration-to-progress based on next output buffer presentation time in MediaCodecVideoRenderer.

Public methods

synchronized static void

Explicitly disables a flag, overriding the canary mode default.

synchronized static void

Explicitly enables a flag, overriding the canary mode default.

static int[]

Returns the flag identifiers that are explicitly disabled via disableFlag, overriding the canary mode default.

static int[]

Returns the flag identifiers that are explicitly enabled via enableFlag, overriding the canary mode default.

static String

Returns a log string describing the current canary mode and flag override state.

static boolean

Returns whether canary mode is currently enabled.

static boolean
isEnabled(@Flags.Flag int flag)

Checks if a specific flag is enabled.

synchronized static void

Resets the flag registry to its default configuration (all overrides cleared, canary mode enabled).

synchronized static void
setCanaryModeEnabled(boolean enabled)

Sets whether canary mode is enabled globally.

Constants

FLAG_DYNAMIC_SCHEDULING

@ExperimentalApi
public static final int FLAG_DYNAMIC_SCHEDULING = 3

Flag to enable dynamic scheduling in ExoPlayer.

When enabled, ExoPlayer uses dynamic scheduling for its playback loop.

This flag is statically enabled and defaults to true.

FLAG_ENABLE_CLIPPING_IN_MEDIA_PERIOD

@ExperimentalApi
public static final int FLAG_ENABLE_CLIPPING_IN_MEDIA_PERIOD = 5

Flag to enable delegating end-position clipping to MediaPeriod instances in ExoPlayer.

When enabled, clipping of the end position is delegated to the wrapped MediaPeriod rather than being handled at the media source level.

This flag is not yet covered by canary mode and defaults to false.

FLAG_ENABLE_MEDIACODEC_BUFFER_DECODE_ONLY

@ExperimentalApi
public static final int FLAG_ENABLE_MEDIACODEC_BUFFER_DECODE_ONLY = 6

Flag to enable passing BUFFER_FLAG_DECODE_ONLY to android.media.MediaCodec on API 34+.

When enabled on API 34+, buffers before the start time in non-tunneling mode are queued with BUFFER_FLAG_DECODE_ONLY rather than being dropped after decoding.

This flag is not yet covered by canary mode and defaults to false.

FLAG_ENABLE_STUCK_PLAYING_DETECTION

@ExperimentalApi
public static final int FLAG_ENABLE_STUCK_PLAYING_DETECTION = 4

Flag to enable stuck playing detection in ExoPlayer.

When enabled, ExoPlayer detects when playback is stuck without making progress or without ending, and triggers a playback error.

FLAG_ENFORCE_PARSABLE_BYTE_ARRAY_LIMIT

@ExperimentalApi
public static final int FLAG_ENFORCE_PARSABLE_BYTE_ARRAY_LIMIT = 8

Flag to enable enforcing that read and peek methods in ParsableByteArray do not read beyond limit.

When enabled, reading or peeking beyond the limit throws an IndexOutOfBoundsException (or java.nio.BufferOverflowException) even if the read is within the bounds of the underlying byte array.

FLAG_PARSE_DASH_ALTERNATIVE_MPD_EVENTS

@ExperimentalApi
public static final int FLAG_PARSE_DASH_ALTERNATIVE_MPD_EVENTS = 11

Flag to enable parsing DASH Alternative MPD events into Period.alternativeMpdEvents in DashManifestParser.

When enabled, DashManifestParser parses Alternative MPD EventStreams into both Period.eventStreams and Period.alternativeMpdEvents. When disabled, only Period.eventStreams is populated using standard EventStream parsing.

FLAG_PER_STREAM_MEDIA_PROGRESSION

@ExperimentalApi
public static final int FLAG_PER_STREAM_MEDIA_PROGRESSION = 1

Flag to enable per-stream media progression in ExoPlayer.

When enabled, ExoPlayer may advance processing on a per-stream basis, potentially starting to process the next item in the playlist before finishing the current one. This can reduce startup latency between media items.

This flag is not yet covered by canary mode and defaults to false.

FLAG_PLAY_PAUSE_AUDIO_TRACK_ON_INIT

@ExperimentalApi
public static final int FLAG_PLAY_PAUSE_AUDIO_TRACK_ON_INIT = 10

Flag to enable calling play and pause immediately after creating an android.media.AudioTrack.

When enabled, calling play() and pause() at initialization time triggers internal android.media.AudioTrack initialization to reduce startup latency on the first actual playback.

This flag is not yet covered by canary mode and defaults to false.

FLAG_PROCESSED_STREAM_CHANGED_AT_START

@ExperimentalApi
public static final int FLAG_PROCESSED_STREAM_CHANGED_AT_START = 2

Flag to enable invoking MediaCodecRenderer.onProcessedStreamChange() on the first stream.

When enabled, onProcessedStreamChange() is invoked starting from the first stream. When disabled (the default), it is invoked from the second stream onwards.

This flag is not yet covered by canary mode and defaults to false.

FLAG_SKIP_AUDIO_TRACK_FLUSH_BEFORE_RELEASE

@ExperimentalApi
public static final int FLAG_SKIP_AUDIO_TRACK_FLUSH_BEFORE_RELEASE = 9

Flag to skip calling flush before release on API 29+.

When enabled on API 29+, AudioTrackAudioOutput releases the underlying android.media.AudioTrack without calling flush() first.

FLAG_VIDEO_RENDERER_DURATION_TO_PROGRESS

@ExperimentalApi
public static final int FLAG_VIDEO_RENDERER_DURATION_TO_PROGRESS = 7

Flag to enable calculating duration-to-progress based on next output buffer presentation time in MediaCodecVideoRenderer.

When enabled along with FLAG_DYNAMIC_SCHEDULING, MediaCodecVideoRenderer returns duration-to-progress aligned with when its next output buffer can be rendered when in asynchronous mode.

This flag is not yet covered by canary mode and defaults to false.

Public methods

disableFlag

synchronized public static void disableFlag(@Flags.Flag int flag)

Explicitly disables a flag, overriding the canary mode default.

This must be called before creating any Media3 components.

Parameters
@Flags.Flag int flag

The flag identifier.

enableFlag

synchronized public static void enableFlag(@Flags.Flag int flag)

Explicitly enables a flag, overriding the canary mode default.

This must be called before creating any Media3 components.

Parameters
@Flags.Flag int flag

The flag identifier.

getDisabledOverrides

@Flags.Flag
public static int[] getDisabledOverrides()

Returns the flag identifiers that are explicitly disabled via disableFlag, overriding the canary mode default.

getEnabledOverrides

@Flags.Flag
public static int[] getEnabledOverrides()

Returns the flag identifiers that are explicitly enabled via enableFlag, overriding the canary mode default.

getLogString

public static String getLogString()

Returns a log string describing the current canary mode and flag override state.

The format is [Canary:<state>, Overrides: enabled=[<ids>], disabled=[<ids>]], or [Canary:<state>] if there are no overrides. Only deviations from the default state are listed.

isCanaryModeEnabled

public static boolean isCanaryModeEnabled()

Returns whether canary mode is currently enabled.

isEnabled

public static boolean isEnabled(@Flags.Flag int flag)

Checks if a specific flag is enabled.

The resolution order is:

  1. If the flag has an explicit override (via enableFlag or disableFlag), the override value is returned.
  2. If the flag has a static value not part of canary mode, that static value is returned.
  3. Otherwise, the flag is enabled if canary mode is enabled.
Parameters
@Flags.Flag int flag

The flag identifier.

Returns
boolean

Whether the flag is enabled.

resetForTesting

@VisibleForTesting
synchronized public static void resetForTesting()

Resets the flag registry to its default configuration (all overrides cleared, canary mode enabled).

This is intended for use in tests only to avoid test pollution. In unit tests, androidx.media3.test.utils.Media3FlagsRule is the preferred alternative to calling this method directly.

setCanaryModeEnabled

synchronized public static void setCanaryModeEnabled(boolean enabled)

Sets whether canary mode is enabled globally.

Canary mode is enabled by default.

When enabled, all flags that are not statically excluded are active by default. Individual overrides set via enableFlag or disableFlag take precedence.

This must be called before creating any Media3 components.

Parameters
boolean enabled

Whether to enable canary mode.