1616package androidx .media3 .exoplayer .trackselection ;
1717
1818import static android .os .Build .VERSION .SDK_INT ;
19+ import static androidx .media3 .common .C .ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND ;
20+ import static androidx .media3 .common .C .ROLE_FLAG_DESCRIBES_VIDEO ;
1921import static androidx .media3 .common .TrackSelectionParameters .AudioOffloadPreferences .AUDIO_OFFLOAD_MODE_DISABLED ;
2022import static androidx .media3 .common .TrackSelectionParameters .AudioOffloadPreferences .AUDIO_OFFLOAD_MODE_REQUIRED ;
2123import static androidx .media3 .common .util .Assertions .checkNotNull ;
3436import android .media .AudioFormat ;
3537import android .media .AudioManager ;
3638import android .media .Spatializer ;
39+ import android .os .Build ;
3740import android .os .Bundle ;
3841import android .os .Handler ;
3942import android .os .Looper ;
4043import android .text .TextUtils ;
4144import android .util .Pair ;
4245import android .util .SparseArray ;
4346import android .util .SparseBooleanArray ;
47+ import android .view .accessibility .AccessibilityManager ;
4448import android .view .accessibility .CaptioningManager ;
4549import androidx .annotation .GuardedBy ;
4650import androidx .annotation .IntDef ;
@@ -402,6 +406,14 @@ public ParametersBuilder setPreferredAudioRoleFlags(@C.RoleFlags int preferredAu
402406 return this ;
403407 }
404408
409+ @ SuppressWarnings ("deprecation" ) // Intentionally returning deprecated type
410+ @ CanIgnoreReturnValue
411+ @ Override
412+ public ParametersBuilder setPreferredAudioRoleFlagsFromAccessibilityManager () {
413+ delegate .setPreferredAudioRoleFlagsFromAccessibilityManager ();
414+ return this ;
415+ }
416+
405417 @ SuppressWarnings ("deprecation" ) // Intentionally returning deprecated type
406418 @ CanIgnoreReturnValue
407419 @ Override
@@ -1225,6 +1237,13 @@ public Builder setPreferredAudioRoleFlags(@C.RoleFlags int preferredAudioRoleFla
12251237 return this ;
12261238 }
12271239
1240+ @ CanIgnoreReturnValue
1241+ @ Override
1242+ public Builder setPreferredAudioRoleFlagsFromAccessibilityManager () {
1243+ super .setPreferredAudioRoleFlagsFromAccessibilityManager ();
1244+ return this ;
1245+ }
1246+
12281247 @ CanIgnoreReturnValue
12291248 @ Override
12301249 public Builder setMaxAudioChannelCount (int maxAudioChannelCount ) {
@@ -2850,7 +2869,13 @@ protected Pair<ExoTrackSelection.Definition, Integer> selectAudioTrack(
28502869 break ;
28512870 }
28522871 }
2872+
2873+ @ RoleFlags int preferredRoleFlagFromAccessibilityManager = 0 ;
2874+ if (SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
2875+ preferredRoleFlagFromAccessibilityManager = getPreferredRoleFlagFromAccessibilityManager (context );
2876+ }
28532877 boolean hasVideoRendererWithMappedTracksFinal = hasVideoRendererWithMappedTracks ;
2878+ @ RoleFlags int preferredRoleFlagFromAccessibilityManagerFinal = preferredRoleFlagFromAccessibilityManager ;
28542879 return selectTracksForType (
28552880 C .TRACK_TYPE_AUDIO ,
28562881 mappedTrackInfo ,
@@ -2863,7 +2888,8 @@ protected Pair<ExoTrackSelection.Definition, Integer> selectAudioTrack(
28632888 support ,
28642889 hasVideoRendererWithMappedTracksFinal ,
28652890 format -> isAudioFormatWithinAudioChannelCountConstraints (format , params ),
2866- rendererMixedMimeTypeAdaptationSupports [rendererIndex ]),
2891+ rendererMixedMimeTypeAdaptationSupports [rendererIndex ],
2892+ preferredRoleFlagFromAccessibilityManagerFinal ),
28672893 AudioTrackInfo ::compareSelections );
28682894 }
28692895
@@ -3530,6 +3556,21 @@ private static String getPreferredLanguageFromCaptioningManager(@Nullable Contex
35303556 return Util .getLocaleLanguageTag (preferredLocale );
35313557 }
35323558
3559+ @ RequiresApi (api = Build .VERSION_CODES .TIRAMISU )
3560+ private static @ RoleFlags int getPreferredRoleFlagFromAccessibilityManager (
3561+ @ Nullable Context context ) {
3562+ if (context == null ) {
3563+ return 0 ;
3564+ }
3565+ AccessibilityManager accessibilityManager = (AccessibilityManager ) context .getSystemService (
3566+ Context .ACCESSIBILITY_SERVICE );
3567+ if (accessibilityManager != null ) {
3568+ return accessibilityManager .isAudioDescriptionRequested () ? ROLE_FLAG_DESCRIBES_VIDEO
3569+ | ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND : 0 ;
3570+ }
3571+ return 0 ;
3572+ }
3573+
35333574 /** Base class for track selection information of a {@link Format}. */
35343575 private abstract static class TrackInfo <T extends TrackInfo <T >> {
35353576 /** Factory for {@link TrackInfo} implementations for a given {@link TrackGroup}. */
@@ -3833,7 +3874,8 @@ public static ImmutableList<AudioTrackInfo> createForTrackGroup(
38333874 @ Capabilities int [] formatSupport ,
38343875 boolean hasMappedVideoTracks ,
38353876 Predicate <Format > withinAudioChannelCountConstraints ,
3836- @ AdaptiveSupport int mixedMimeTypeAdaptationSupport ) {
3877+ @ AdaptiveSupport int mixedMimeTypeAdaptationSupport ,
3878+ @ RoleFlags int preferredRoleFlagFromAccessibilityManager ) {
38373879 ImmutableList .Builder <AudioTrackInfo > listBuilder = ImmutableList .builder ();
38383880 for (int i = 0 ; i < trackGroup .length ; i ++) {
38393881 listBuilder .add (
@@ -3845,7 +3887,8 @@ public static ImmutableList<AudioTrackInfo> createForTrackGroup(
38453887 formatSupport [i ],
38463888 hasMappedVideoTracks ,
38473889 withinAudioChannelCountConstraints ,
3848- mixedMimeTypeAdaptationSupport ));
3890+ mixedMimeTypeAdaptationSupport ,
3891+ preferredRoleFlagFromAccessibilityManager ));
38493892 }
38503893 return listBuilder .build ();
38513894 }
@@ -3879,7 +3922,8 @@ public AudioTrackInfo(
38793922 @ Capabilities int formatSupport ,
38803923 boolean hasMappedVideoTracks ,
38813924 Predicate <Format > withinAudioChannelCountConstraints ,
3882- @ AdaptiveSupport int mixedMimeTypeAdaptationSupport ) {
3925+ @ AdaptiveSupport int mixedMimeTypeAdaptationSupport ,
3926+ @ RoleFlags int preferredRoleFlagFromAccessibilityManager ) {
38833927 super (rendererIndex , trackGroup , trackIndex );
38843928 this .parameters = parameters ;
38853929 @ SuppressLint ("WrongConstant" )
@@ -3910,8 +3954,10 @@ public AudioTrackInfo(
39103954 }
39113955 preferredLanguageIndex = bestLanguageIndex ;
39123956 preferredLanguageScore = bestLanguageScore ;
3913- preferredRoleFlagsScore =
3914- getRoleFlagMatchScore (format .roleFlags , parameters .preferredAudioRoleFlags );
3957+ @ RoleFlags int preferredAudioRoleFlags =
3958+ preferredRoleFlagFromAccessibilityManager == 0 ? parameters .preferredAudioRoleFlags
3959+ : preferredRoleFlagFromAccessibilityManager ;
3960+ preferredRoleFlagsScore = getRoleFlagMatchScore (format .roleFlags , preferredAudioRoleFlags );
39153961 hasMainOrNoRoleFlag = format .roleFlags == 0 || (format .roleFlags & C .ROLE_FLAG_MAIN ) != 0 ;
39163962 isDefaultSelectionFlag = (format .selectionFlags & C .SELECTION_FLAG_DEFAULT ) != 0 ;
39173963 isObjectBasedAudio = isObjectBasedAudio (format );
0 commit comments