Compare commits

..

13 Commits

Author SHA1 Message Date
kimvde
4d68243158 Only join video graph output in playlist mode.
DefaultVideoSink.join() was called when join() was called on the
InputVideoSink. This makes sense in playlist mode but we shouldn't
join if the VideoGraph output is considered as a single clip.

This change is no-op. Indeed, for CompositionPlayer, the
allowedJoiningTimeMs is set to 0, so that join doesn't have any effect.

PiperOrigin-RevId: 750238085
2025-04-22 10:15:18 -07:00
kimvde
fe10ca2c9a Start and stop video rendering from CompositionPlayer
Before, we were starting and stopping video rendering when the
renderers were started/stopped. This doesn't work for multi-video
sequences though because we shouldn't stop and start rendering at every
MediaItem transition in any of the input sequences.

PiperOrigin-RevId: 750206410
2025-04-22 08:43:21 -07:00
jbibik
ab6b0f6e10 [ui-compose] Eliminated race condition inside button state
A bug was introduced because it was unclear that button state creation and listener registration were not an atomic operation. This happens because the `LaunchedEffect` which starts the listen-to-Player-Events coroutine can be pre-empted with other side effects, including the ones that change something in the Player.

`remember*State` functions create some button state object and initialise it with the correct fresh values pulled out of the Player. The subscription to Player events with a registration of a Listener(via `*ButtonState.observe()`) is not immediate. It *returns* immediately, but is instead scheduled to happen *later*, although within the same Handler message. Other LaunchedEffects could have been scheduled earlier and could take place between the button state creation and listener subscription.

This is not a problem if no changes to the player happen, but if we miss the *relevant* player events, we might end up with a UI that is out of sync with reality (e.g. button enabled/disabled when it should be flipped, icons toggled the wrong way). The way to fix this is to pull the latest values out of the Player on demand upon starting to listen to Player events.

PiperOrigin-RevId: 750183793
2025-04-22 07:31:19 -07:00
tonihei
1c855a8abf Remove unneeded SDK checks
PiperOrigin-RevId: 750172684
2025-04-22 06:48:41 -07:00
Copybara-Service
661effcddd Merge pull request #2323 from DolbyLaboratories:dlb/ac4-profile/dev
PiperOrigin-RevId: 750171380
2025-04-22 06:43:36 -07:00
michaelkatz
d3328456a7 Allow trailing whitespace in RTSP SessionDescription lines
This CL fixes the parser for the RTSP SessionDescription such that it will not choke if there is trailing whitespace in the lines.

PiperOrigin-RevId: 750158624
2025-04-22 05:53:56 -07:00
kimvde
ba97999657 Fix compilation error
Patterns in instanceof are not supported on Java 8.

PiperOrigin-RevId: 750147834
2025-04-22 05:12:58 -07:00
Copybara-Service
4d9f47920a Merge pull request #2285 from MGaetan89:deprecate_util_sdkint
PiperOrigin-RevId: 750142132
2025-04-22 04:53:39 -07:00
tonihei
ea837aa718 Remove release notes
Deprecatations don't need to be noted
2025-04-17 16:02:33 +01:00
Gaëtan Muller
340264e376 Update release notes 2025-04-17 15:59:01 +01:00
Gaëtan Muller
9b2e1cfca0 Deprecate Util.SDK_INT in favor of Build.VERSION.SDK_INT
`Util.SDK_INT` was introduced to be able to simulate any SDK version during tests.
This is possible by using Robolectric's `@Config(sdk)` annotation.
All usages of `Util.SDK_INT` have been replaced by `Build.VERSION.SDK_INT`.

This is a similar change to what was done in #2107.
2025-04-17 15:55:23 +01:00
ybai001
2500d91848 Add KEY_PROFILE, KEY_LEVEL support for AC-4 2025-04-10 09:39:23 +08:00
ybai001
28feb7bab5
Merge pull request #17 from androidx/main
Merge from androidx/main
2025-04-02 11:31:17 +08:00
217 changed files with 1049 additions and 604 deletions

View File

@ -54,6 +54,11 @@
connected to a legacy `MediaBrowserServiceCompat` produced a
`NullPointerException`.
* UI:
* Fix a Compose bug which resulted in a gap between setting the initial
button states and observing the change in state (e.g. icon shapes or
being enabled). Any changes made to the Player outside of the
observation period are now picked up
([#2313](https://github.com/androidx/media/issues/2313)).
* Downloads:
* Add partial download support for progressive streams. Apps can prepare a
progressive stream with `DownloadHelper`, and request a
@ -73,6 +78,9 @@
* DASH extension:
* Smooth Streaming extension:
* RTSP extension:
* Add parsing support for SessionDescriptions containing lines with
trailing whitespace characters
([#2357](https://github.com/androidx/media/issues/2357)).
* Decoder extensions (FFmpeg, VP9, AV1, etc.):
* MIDI extension:
* Leanback extension:

View File

@ -16,7 +16,7 @@
package androidx.media3.demo.composition;
import static android.content.pm.ActivityInfo.COLOR_MODE_HDR;
import static androidx.media3.common.util.Util.SDK_INT;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.transformer.Composition.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR;
import static androidx.media3.transformer.Composition.HDR_MODE_KEEP_HDR;
import static androidx.media3.transformer.Composition.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC;

View File

@ -17,6 +17,7 @@ package androidx.media3.demo.effect
import android.Manifest
import android.net.Uri
import android.os.Build.VERSION.SDK_INT
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
@ -81,7 +82,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.media3.common.Effect
import androidx.media3.common.MediaItem
import androidx.media3.common.util.UnstableApi
import androidx.media3.common.util.Util.SDK_INT
import androidx.media3.effect.Contrast
import androidx.media3.effect.OverlayEffect
import androidx.media3.effect.StaticOverlaySettings

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.demo.gl;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.app.Activity;
@ -94,7 +95,7 @@ public final class MainActivity extends Activity {
@Override
public void onStart() {
super.onStart();
if (Util.SDK_INT > 23) {
if (SDK_INT > 23) {
initializePlayer();
if (playerView != null) {
playerView.onResume();
@ -105,7 +106,7 @@ public final class MainActivity extends Activity {
@Override
public void onResume() {
super.onResume();
if (Util.SDK_INT <= 23 || player == null) {
if (SDK_INT <= 23 || player == null) {
initializePlayer();
if (playerView != null) {
playerView.onResume();
@ -116,7 +117,7 @@ public final class MainActivity extends Activity {
@Override
public void onPause() {
super.onPause();
if (Util.SDK_INT <= 23) {
if (SDK_INT <= 23) {
if (playerView != null) {
playerView.onPause();
}
@ -127,7 +128,7 @@ public final class MainActivity extends Activity {
@Override
public void onStop() {
super.onStop();
if (Util.SDK_INT > 23) {
if (SDK_INT > 23) {
if (playerView != null) {
playerView.onPause();
}

View File

@ -17,8 +17,8 @@ package androidx.media3.demo.transformer;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.READ_MEDIA_VIDEO;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Util.SDK_INT;
import static androidx.media3.transformer.Composition.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR;
import static androidx.media3.transformer.Composition.HDR_MODE_KEEP_HDR;
import static androidx.media3.transformer.Composition.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC;

View File

@ -16,6 +16,7 @@
package androidx.media3.demo.transformer;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.exoplayer.DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
@ -985,14 +986,14 @@ public final class TransformerActivity extends AppCompatActivity {
.setOngoing(true)
.setSmallIcon(R.drawable.exo_icon_play)
.build();
if (Util.SDK_INT >= 26) {
if (SDK_INT >= 26) {
NotificationChannel channel =
new NotificationChannel(
CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
startForeground(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION);
} else {
startForeground(NOTIFICATION_ID, notification);

View File

@ -15,9 +15,9 @@
*/
package androidx.media3.cast;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.SDK_INT;
import static androidx.media3.common.util.Util.castNonNull;
import static java.lang.Math.min;

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.common;
import static android.os.Build.VERSION.SDK_INT;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
@ -45,10 +47,10 @@ public final class AudioAttributes {
.setContentType(audioAttributes.contentType)
.setFlags(audioAttributes.flags)
.setUsage(audioAttributes.usage);
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
Api29.setAllowedCapturePolicy(builder, audioAttributes.allowedCapturePolicy);
}
if (Util.SDK_INT >= 32) {
if (SDK_INT >= 32) {
Api32.setSpatializationBehavior(builder, audioAttributes.spatializationBehavior);
}
this.audioAttributes = builder.build();

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.common;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.os.Binder;
@ -25,7 +26,6 @@ import android.os.RemoteException;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.common.collect.ImmutableList;
import java.util.List;
@ -56,7 +56,7 @@ public final class BundleListRetriever extends Binder {
// Soft limit of an IPC buffer size
private static final int SUGGESTED_MAX_IPC_SIZE =
Util.SDK_INT >= 30 ? IBinder.getSuggestedMaxIpcSizeBytes() : 64 * 1024;
SDK_INT >= 30 ? IBinder.getSuggestedMaxIpcSizeBytes() : 64 * 1024;
private static final int REPLY_END_OF_LIST = 0;
private static final int REPLY_CONTINUE = 1;

View File

@ -15,13 +15,13 @@
*/
package androidx.media3.common;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkIndex;
import static androidx.media3.common.util.Assertions.checkState;
import android.util.SparseBooleanArray;
import androidx.annotation.Nullable;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
/**
@ -222,7 +222,7 @@ public final class FlagSet {
return false;
}
FlagSet that = (FlagSet) o;
if (Util.SDK_INT < 24) {
if (SDK_INT < 24) {
// SparseBooleanArray.equals() is not implemented on API levels below 24.
if (size() != that.size()) {
return false;
@ -240,7 +240,7 @@ public final class FlagSet {
@Override
public int hashCode() {
if (Util.SDK_INT < 24) {
if (SDK_INT < 24) {
// SparseBooleanArray.hashCode() is not implemented on API levels below 24.
int hashCode = size();
for (int i = 0; i < size(); i++) {

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.common.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
@ -55,7 +56,7 @@ public final class AudioFocusRequestCompat {
this.audioAttributes = audioFocusRequestCompat;
this.pauseOnDuck = pauseOnDuck;
if (Util.SDK_INT < 26) {
if (SDK_INT < 26) {
this.onAudioFocusChangeListener =
new OnAudioFocusChangeListenerHandlerCompat(
onAudioFocusChangeListener, focusChangeHandler);
@ -63,7 +64,7 @@ public final class AudioFocusRequestCompat {
this.onAudioFocusChangeListener = onAudioFocusChangeListener;
}
if (Util.SDK_INT >= 26) {
if (SDK_INT >= 26) {
this.frameworkAudioFocusRequest =
new AudioFocusRequest.Builder(focusGain)
.setAudioAttributes(audioAttributes.getAudioAttributesV21().audioAttributes)

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.common.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static java.lang.annotation.ElementType.TYPE_USE;
@ -29,7 +30,6 @@ import androidx.media3.common.util.BackgroundExecutor;
import androidx.media3.common.util.ConditionVariable;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -154,7 +154,7 @@ public final class AudioManagerCompat {
@SuppressWarnings("deprecation")
public static int requestAudioFocus(
AudioManager audioManager, AudioFocusRequestCompat focusRequest) {
if (Util.SDK_INT >= 26) {
if (SDK_INT >= 26) {
return audioManager.requestAudioFocus(focusRequest.getAudioFocusRequest());
} else {
return audioManager.requestAudioFocus(
@ -176,7 +176,7 @@ public final class AudioManagerCompat {
@SuppressWarnings("deprecation")
public static int abandonAudioFocusRequest(
AudioManager audioManager, AudioFocusRequestCompat focusRequest) {
if (Util.SDK_INT >= 26) {
if (SDK_INT >= 26) {
return audioManager.abandonAudioFocusRequest(focusRequest.getAudioFocusRequest());
} else {
return audioManager.abandonAudioFocus(focusRequest.getOnAudioFocusChangeListener());
@ -204,7 +204,7 @@ public final class AudioManagerCompat {
*/
@IntRange(from = 0)
public static int getStreamMinVolume(AudioManager audioManager, @C.StreamType int streamType) {
return Util.SDK_INT >= 28 ? audioManager.getStreamMinVolume(streamType) : 0;
return SDK_INT >= 28 ? audioManager.getStreamMinVolume(streamType) : 0;
}
/**
@ -233,7 +233,7 @@ public final class AudioManagerCompat {
* @return Whether the stream is muted.
*/
public static boolean isStreamMute(AudioManager audioManager, @C.StreamType int streamType) {
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
return audioManager.isStreamMute(streamType);
} else {
return getStreamVolume(audioManager, streamType) == 0;

View File

@ -62,6 +62,8 @@ public final class CodecSpecificDataUtil {
private static final String CODEC_ID_AV01 = "av01";
// MP4A AAC.
private static final String CODEC_ID_MP4A = "mp4a";
// AC-4
private static final String CODEC_ID_AC4 = "ac-4";
private static final Pattern PROFILE_PATTERN = Pattern.compile("^\\D?(\\d+)$");
@ -350,6 +352,8 @@ public final class CodecSpecificDataUtil {
return getAv1ProfileAndLevel(format.codecs, parts, format.colorInfo);
case CODEC_ID_MP4A:
return getAacCodecProfileAndLevel(format.codecs, parts);
case CODEC_ID_AC4:
return getAc4CodecProfileAndLevel(format.codecs, parts);
default:
return null;
}
@ -763,6 +767,41 @@ public final class CodecSpecificDataUtil {
return null;
}
@Nullable
private static Pair<Integer, Integer> getAc4CodecProfileAndLevel(String codec, String[] parts) {
if (parts.length != 4) {
Log.w(TAG, "Ignoring malformed AC-4 codec string: " + codec);
return null;
}
int bitstreamVersionInteger;
int presentationVersionInteger;
int levelInteger;
try {
bitstreamVersionInteger = Integer.parseInt(parts[1]);
presentationVersionInteger = Integer.parseInt(parts[2]);
levelInteger = Integer.parseInt(parts[3]);
} catch (NumberFormatException e) {
Log.w(TAG, "Ignoring malformed AC-4 codec string: " + codec);
return null;
}
int profile =
ac4BitstreamAndPresentationVersionsToProfileConst(
bitstreamVersionInteger, presentationVersionInteger);
if (profile == -1) {
Log.w(
TAG,
"Unknown AC-4 profile: " + bitstreamVersionInteger + "." + presentationVersionInteger);
return null;
}
int level = ac4LevelNumberToConst(levelInteger);
if (level == -1) {
Log.w(TAG, "Unknown AC-4 level: " + levelInteger);
return null;
}
return new Pair<>(profile, level);
}
private static int avcProfileNumberToConst(int profileNumber) {
switch (profileNumber) {
case 66:
@ -1094,5 +1133,51 @@ public final class CodecSpecificDataUtil {
}
}
private static int ac4BitstreamAndPresentationVersionsToProfileConst(
int bitstreamVersionInteger, int presentationVersionInteger) {
int ac4Profile = -1;
switch (bitstreamVersionInteger) {
case 0:
if (presentationVersionInteger == 0) {
ac4Profile = MediaCodecInfo.CodecProfileLevel.AC4Profile00;
}
break;
case 1:
if (presentationVersionInteger == 0) {
ac4Profile = MediaCodecInfo.CodecProfileLevel.AC4Profile10;
} else if (presentationVersionInteger == 1) {
ac4Profile = MediaCodecInfo.CodecProfileLevel.AC4Profile11;
}
break;
case 2:
if (presentationVersionInteger == 1) {
ac4Profile = MediaCodecInfo.CodecProfileLevel.AC4Profile21;
} else if (presentationVersionInteger == 2) {
ac4Profile = MediaCodecInfo.CodecProfileLevel.AC4Profile22;
}
break;
default:
break;
}
return ac4Profile;
}
private static int ac4LevelNumberToConst(int levelNumber) {
switch (levelNumber) {
case 0:
return MediaCodecInfo.CodecProfileLevel.AC4Level0;
case 1:
return MediaCodecInfo.CodecProfileLevel.AC4Level1;
case 2:
return MediaCodecInfo.CodecProfileLevel.AC4Level2;
case 3:
return MediaCodecInfo.CodecProfileLevel.AC4Level3;
case 4:
return MediaCodecInfo.CodecProfileLevel.AC4Level4;
default:
return -1;
}
}
private CodecSpecificDataUtil() {}
}

View File

@ -17,6 +17,7 @@ package androidx.media3.common.util;
import static android.opengl.EGL14.EGL_CONTEXT_CLIENT_VERSION;
import static android.opengl.GLU.gluErrorString;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkState;
@ -169,18 +170,17 @@ public final class GlUtil {
* <p>If {@code true}, the device supports a protected output path for DRM content when using GL.
*/
public static boolean isProtectedContentExtensionSupported(Context context) {
if (Util.SDK_INT < 24) {
if (SDK_INT < 24) {
return false;
}
if (Util.SDK_INT < 26
&& ("samsung".equals(Build.MANUFACTURER) || "XT1650".equals(Build.MODEL))) {
if (SDK_INT < 26 && ("samsung".equals(Build.MANUFACTURER) || "XT1650".equals(Build.MODEL))) {
// Samsung devices running Nougat are known to be broken. See
// https://github.com/google/ExoPlayer/issues/3373 and [Internal: b/37197802].
// Moto Z XT1650 is also affected. See
// https://github.com/google/ExoPlayer/issues/3215.
return false;
}
if (Util.SDK_INT < 26
if (SDK_INT < 26
&& !context
.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
@ -242,7 +242,7 @@ public final class GlUtil {
public static boolean isBt2020PqExtensionSupported() {
// On API<33, the system cannot display PQ content correctly regardless of whether BT2020 PQ
// GL extension is supported. Context: http://b/252537203#comment5.
return Util.SDK_INT >= 33 && isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ);
return SDK_INT >= 33 && isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ);
}
/** Returns whether {@link #EXTENSION_COLORSPACE_BT2020_HLG} is supported. */

View File

@ -15,7 +15,7 @@
*/
package androidx.media3.common.util;
import static androidx.media3.common.util.Util.SDK_INT;
import static android.os.Build.VERSION.SDK_INT;
import android.annotation.SuppressLint;
import android.media.AudioFormat;

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.common.util;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.annotation.SuppressLint;
@ -159,7 +160,7 @@ public final class NetworkTypeObserver {
private void handleConnectivityActionBroadcast(Context context) {
@C.NetworkType int networkType = getNetworkTypeFromConnectivityManager(context);
if (Util.SDK_INT >= 31 && networkType == C.NETWORK_TYPE_4G) {
if (SDK_INT >= 31 && networkType == C.NETWORK_TYPE_4G) {
// Delay update of the network type to check whether this is actually 5G-NSA.
Api31.disambiguate4gAnd5gNsa(context, /* instance= */ NetworkTypeObserver.this);
} else {
@ -239,7 +240,7 @@ public final class NetworkTypeObserver {
case TelephonyManager.NETWORK_TYPE_LTE:
return C.NETWORK_TYPE_4G;
case TelephonyManager.NETWORK_TYPE_NR:
return Util.SDK_INT >= 29 ? C.NETWORK_TYPE_5G_SA : C.NETWORK_TYPE_UNKNOWN;
return SDK_INT >= 29 ? C.NETWORK_TYPE_5G_SA : C.NETWORK_TYPE_UNKNOWN;
case TelephonyManager.NETWORK_TYPE_IWLAN:
return C.NETWORK_TYPE_WIFI;
case TelephonyManager.NETWORK_TYPE_GSM:

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.common.util;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static java.lang.annotation.ElementType.TYPE_USE;
@ -113,7 +114,7 @@ public final class NotificationUtil {
@StringRes int nameResourceId,
@StringRes int descriptionResourceId,
@Importance int importance) {
if (Util.SDK_INT >= 26) {
if (SDK_INT >= 26) {
NotificationManager notificationManager =
checkNotNull(
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));

View File

@ -155,10 +155,9 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
public final class Util {
/**
* Like {@link Build.VERSION#SDK_INT}, but in a place where it can be conveniently overridden for
* local testing.
* @deprecated Use {@link Build.VERSION#SDK_INT} instead.
*/
@UnstableApi public static final int SDK_INT = Build.VERSION.SDK_INT;
@UnstableApi @Deprecated public static final int SDK_INT = Build.VERSION.SDK_INT;
/**
* @deprecated Use {@link Build#DEVICE} instead.
@ -178,7 +177,7 @@ public final class Util {
/** A concise description of the device that it can be useful to log for debugging purposes. */
@UnstableApi
public static final String DEVICE_DEBUG_INFO =
Build.DEVICE + ", " + Build.MODEL + ", " + Build.MANUFACTURER + ", " + SDK_INT;
Build.DEVICE + ", " + Build.MODEL + ", " + Build.MANUFACTURER + ", " + Build.VERSION.SDK_INT;
/** An empty byte array. */
@UnstableApi public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
@ -249,7 +248,7 @@ public final class Util {
/**
* Registers a {@link BroadcastReceiver} that's not intended to receive broadcasts from other
* apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link
* #SDK_INT} is 33 or above.
* Build.VERSION#SDK_INT} is 33 or above.
*
* <p>Do not use this method if registering a receiver for a <a
* href="https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml">protected
@ -264,7 +263,7 @@ public final class Util {
@Nullable
public static Intent registerReceiverNotExported(
Context context, @Nullable BroadcastReceiver receiver, IntentFilter filter) {
if (SDK_INT < 33) {
if (Build.VERSION.SDK_INT < 33) {
return context.registerReceiver(receiver, filter);
} else {
return context.registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED);
@ -272,8 +271,8 @@ public final class Util {
}
/**
* Calls {@link Context#startForegroundService(Intent)} if {@link #SDK_INT} is 26 or higher, or
* {@link Context#startService(Intent)} otherwise.
* Calls {@link Context#startForegroundService(Intent)} if {@link Build.VERSION#SDK_INT} is 26 or
* higher, or {@link Context#startService(Intent)} otherwise.
*
* @param context The context to call.
* @param intent The intent to pass to the called method.
@ -282,7 +281,7 @@ public final class Util {
@UnstableApi
@Nullable
public static ComponentName startForegroundService(Context context, Intent intent) {
if (SDK_INT >= 26) {
if (Build.VERSION.SDK_INT >= 26) {
return context.startForegroundService(intent);
} else {
return context.startService(intent);
@ -307,7 +306,7 @@ public final class Util {
Notification notification,
int foregroundServiceType,
String foregroundServiceManifestType) {
if (Util.SDK_INT >= 29) {
if (Build.VERSION.SDK_INT >= 29) {
Api29.startForeground(
service,
notificationId,
@ -352,7 +351,7 @@ public final class Util {
*/
public static boolean maybeRequestReadStoragePermission(
Activity activity, MediaItem... mediaItems) {
if (SDK_INT < 23) {
if (Build.VERSION.SDK_INT < 23) {
return false;
}
for (MediaItem mediaItem : mediaItems) {
@ -377,7 +376,7 @@ public final class Util {
if (!isReadStoragePermissionRequestNeeded(activity, uri)) {
return false;
}
if (SDK_INT < 33) {
if (Build.VERSION.SDK_INT < 33) {
return requestExternalStoragePermission(activity);
} else {
return requestReadMediaPermissions(activity);
@ -386,7 +385,7 @@ public final class Util {
@ChecksSdkIntAtLeast(api = 23)
private static boolean isReadStoragePermissionRequestNeeded(Activity activity, Uri uri) {
if (SDK_INT < 23) {
if (Build.VERSION.SDK_INT < 23) {
// Permission automatically granted via manifest below API 23.
return false;
}
@ -440,7 +439,7 @@ public final class Util {
* @return Whether it may be possible to load the URIs of the given media items.
*/
public static boolean checkCleartextTrafficPermitted(MediaItem... mediaItems) {
if (SDK_INT < 24) {
if (Build.VERSION.SDK_INT < 24) {
// We assume cleartext traffic is permitted.
return true;
}
@ -511,7 +510,7 @@ public final class Util {
return false;
}
if (Util.SDK_INT >= 31) {
if (Build.VERSION.SDK_INT >= 31) {
return sparseArray1.contentEquals(sparseArray2);
}
@ -540,7 +539,7 @@ public final class Util {
*/
@UnstableApi
public static <T> int contentHashCode(SparseArray<T> sparseArray) {
if (Util.SDK_INT >= 31) {
if (Build.VERSION.SDK_INT >= 31) {
return sparseArray.contentHashCode();
}
int hash = 17;
@ -2296,7 +2295,7 @@ public final class Util {
case 8:
return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
case 10:
if (Util.SDK_INT >= 32) {
if (Build.VERSION.SDK_INT >= 32) {
return AudioFormat.CHANNEL_OUT_5POINT1POINT4;
} else {
// Before API 32, height channel masks are not available. For those 10-channel streams
@ -2306,7 +2305,7 @@ public final class Util {
case 12:
return AudioFormat.CHANNEL_OUT_7POINT1POINT4;
case 24:
if (Util.SDK_INT >= 32) {
if (Build.VERSION.SDK_INT >= 32) {
return AudioFormat.CHANNEL_OUT_7POINT1POINT4
| AudioFormat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER
| AudioFormat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER
@ -3070,7 +3069,9 @@ public final class Util {
/** Returns the default {@link Locale.Category#DISPLAY DISPLAY} {@link Locale}. */
@UnstableApi
public static Locale getDefaultDisplayLocale() {
return SDK_INT >= 24 ? Locale.getDefault(Locale.Category.DISPLAY) : Locale.getDefault();
return Build.VERSION.SDK_INT >= 24
? Locale.getDefault(Locale.Category.DISPLAY)
: Locale.getDefault();
}
/**
@ -3165,7 +3166,7 @@ public final class Util {
*/
@UnstableApi
public static boolean isAutomotive(Context context) {
return SDK_INT >= 23
return Build.VERSION.SDK_INT >= 23
&& context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
}
@ -3241,7 +3242,7 @@ public final class Util {
// vendor.display-size instead.
@Nullable
String displaySize =
SDK_INT < 28
Build.VERSION.SDK_INT < 28
? getSystemProperty("sys.display-size")
: getSystemProperty("vendor.display-size");
// If we managed to read the display size, attempt to parse it.
@ -3270,7 +3271,7 @@ public final class Util {
}
Point displaySize = new Point();
if (SDK_INT >= 23) {
if (Build.VERSION.SDK_INT >= 23) {
getDisplaySizeV23(display, displaySize);
} else {
display.getRealSize(displaySize);
@ -3324,9 +3325,9 @@ public final class Util {
return true;
case MimeTypes.IMAGE_HEIF:
case MimeTypes.IMAGE_HEIC:
return Util.SDK_INT >= 26;
return Build.VERSION.SDK_INT >= 26;
case MimeTypes.IMAGE_AVIF:
return Util.SDK_INT >= 34;
return Build.VERSION.SDK_INT >= 34;
default:
return false;
}
@ -3526,12 +3527,12 @@ public final class Util {
// full.
// Some devices might drop frames despite setting {@link
// MediaFormat#KEY_ALLOW_FRAME_DROP} to 0. See b/307518793, b/289983935 and b/353487886.
return SDK_INT < 29
return Build.VERSION.SDK_INT < 29
|| context.getApplicationInfo().targetSdkVersion < 29
|| ((SDK_INT == 30
|| ((Build.VERSION.SDK_INT == 30
&& (Ascii.equalsIgnoreCase(Build.MODEL, "moto g(20)")
|| Ascii.equalsIgnoreCase(Build.MODEL, "rmx3231")))
|| (SDK_INT == 34 && Ascii.equalsIgnoreCase(Build.MODEL, "sm-x200")));
|| (Build.VERSION.SDK_INT == 34 && Ascii.equalsIgnoreCase(Build.MODEL, "sm-x200")));
}
/**
@ -3818,7 +3819,7 @@ public final class Util {
private static String[] getSystemLocales() {
Configuration config = Resources.getSystem().getConfiguration();
return SDK_INT >= 24
return Build.VERSION.SDK_INT >= 24
? getSystemLocalesV24(config)
: new String[] {getLocaleLanguageTag(config.locale)};
}

View File

@ -17,6 +17,7 @@ package androidx.media3.common.util;
import static android.net.NetworkInfo.State.CONNECTED;
import static android.net.NetworkInfo.State.DISCONNECTED;
import static android.os.Build.VERSION.SDK_INT;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.mockito.Mockito.mock;
@ -238,7 +239,7 @@ public class NetworkTypeObserverTest {
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Object displayInfo =

View File

@ -15,12 +15,13 @@
*/
package androidx.media3.decoder;
import static android.os.Build.VERSION.SDK_INT;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.media3.common.C;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
/**
* Metadata describing the structure of an encrypted input sample.
@ -90,7 +91,7 @@ public final class CryptoInfo {
public CryptoInfo() {
frameworkCryptoInfo = new android.media.MediaCodec.CryptoInfo();
patternHolder = Util.SDK_INT >= 24 ? new PatternHolderV24(frameworkCryptoInfo) : null;
patternHolder = SDK_INT >= 24 ? new PatternHolderV24(frameworkCryptoInfo) : null;
}
/**
@ -121,7 +122,7 @@ public final class CryptoInfo {
frameworkCryptoInfo.key = key;
frameworkCryptoInfo.iv = iv;
frameworkCryptoInfo.mode = mode;
if (Util.SDK_INT >= 24) {
if (SDK_INT >= 24) {
Assertions.checkNotNull(patternHolder).set(encryptedBlocks, clearBlocks);
}
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.decoder.iamf;
import static android.os.Build.VERSION.SDK_INT;
import static com.google.common.truth.Truth.assertWithMessage;
import android.content.Context;
@ -28,7 +29,6 @@ import androidx.media3.common.AudioAttributes;
import androidx.media3.common.MediaItem;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DefaultDataSource;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.Renderer;
@ -99,7 +99,7 @@ public class IamfPlaybackTest {
@Override
public void run() {
Looper.prepare();
if (Util.SDK_INT >= 32) { // Spatializer is only available on API 32 and above.
if (SDK_INT >= 32) { // Spatializer is only available on API 32 and above.
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
// Lint can't follow the indirection from AudioFormat.ENCODING_PCM_16BIT to
// IamfDecoder.OUTPUT_PCM_ENCODING.

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.decoder.iamf;
import static android.os.Build.VERSION.SDK_INT;
import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioFormat;
@ -92,7 +94,7 @@ public class LibiamfAudioRenderer extends DecoderAudioRenderer<IamfDecoder> {
@SuppressLint("WrongConstant")
private boolean isSpatializationSupported() {
// Spatializer is only available on API 32 and above.
if (Util.SDK_INT < 32) {
if (SDK_INT < 32) {
return false;
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.effect;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -32,7 +33,6 @@ import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.VideoFrameProcessingException;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.TimestampIterator;
import androidx.media3.common.util.Util;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -218,7 +218,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* rboId= */ C.INDEX_UNSET,
frameInfo.format.width,
frameInfo.format.height);
if (Util.SDK_INT >= 34 && bitmap.hasGainmap()) {
if (SDK_INT >= 34 && bitmap.hasGainmap()) {
checkNotNull(repeatingGainmapShaderProgram).setGainmap(checkNotNull(bitmap.getGainmap()));
}
if (signalRepeatingSequence) {

View File

@ -15,9 +15,9 @@
*/
package androidx.media3.effect;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Util.SDK_INT;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import android.opengl.GLES20;

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.effect;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.GlUtil.getDefaultEglDisplay;
import static androidx.media3.effect.DefaultVideoFrameProcessor.WORKING_COLOR_SPACE_DEFAULT;
@ -41,7 +42,6 @@ import androidx.media3.common.VideoFrameProcessingException;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.common.collect.ImmutableList;
import java.util.Objects;
import java.util.concurrent.Executor;
@ -221,7 +221,7 @@ public final class DebugViewShaderProgram implements GlShaderProgram {
// Therefore, convert HLG to PQ below API 34, so that HLG input can be displayed properly on
// API 33.
this.outputColorTransfer =
outputColorTransfer == C.COLOR_TRANSFER_HLG && Util.SDK_INT < 34
outputColorTransfer == C.COLOR_TRANSFER_HLG && SDK_INT < 34
? C.COLOR_TRANSFER_ST2084
: outputColorTransfer;
surfaceView.getHolder().addCallback(this);

View File

@ -17,6 +17,7 @@ package androidx.media3.effect;
import static android.opengl.GLES20.GL_FALSE;
import static android.opengl.GLES20.GL_TRUE;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.VideoFrameProcessor.INPUT_TYPE_BITMAP;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkState;
@ -36,7 +37,6 @@ import androidx.media3.common.util.GlProgram;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.GlUtil.GlException;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.Util;
import androidx.media3.effect.DefaultVideoFrameProcessor.WorkingColorSpace;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
@ -733,7 +733,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (lastGainmap == null) {
return;
}
if (Util.SDK_INT < 34) {
if (SDK_INT < 34) {
throw new IllegalStateException("Gainmaps not supported under API 34.");
}
glProgram.setSamplerTexIdUniform("uGainmapTexSampler", gainmapTexId, /* texUnitIndex= */ 1);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.effect;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -619,7 +620,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
}
if (ColorInfo.isTransferHdr(outputColorInfo)) {
checkArgument(
Util.SDK_INT >= 34 && inputBitmap.hasGainmap(),
SDK_INT >= 34 && inputBitmap.hasGainmap(),
"VideoFrameProcessor configured for HDR output, but either received SDR input, or is on"
+ " an API level that doesn't support gainmaps. SDR to HDR tonemapping is not"
+ " supported.");

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.effect;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -36,7 +37,6 @@ import androidx.media3.common.VideoFrameProcessingException;
import androidx.media3.common.util.GlProgram;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.Util;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
@ -212,7 +212,7 @@ import java.io.IOException;
hdrTypes[i] = HDR_TYPE_TEXT;
overlaySamplersAvailable -= 1;
} else if (overlay instanceof BitmapOverlay) {
checkState(Util.SDK_INT >= 34);
checkState(SDK_INT >= 34);
hdrTypes[i] = HDR_TYPE_ULTRA_HDR;
// Each UltraHDR overlay uses an extra texture to apply the gainmap to the base in the
// shader.

View File

@ -15,8 +15,8 @@
*/
package androidx.media3.effect;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.SDK_INT;
import static java.lang.Math.ceil;
import android.annotation.SuppressLint;

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer;
import static android.os.Build.VERSION.SDK_INT;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.content.Context;
@ -29,7 +30,6 @@ import androidx.media3.common.C;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.audio.AudioRendererEventListener;
import androidx.media3.exoplayer.audio.AudioSink;
import androidx.media3.exoplayer.audio.DefaultAudioSink;
@ -440,7 +440,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
.setMaxDroppedFramesToNotify(MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY)
.experimentalSetParseAv1SampleDependencies(parseAv1SampleDependencies)
.experimentalSetLateThresholdToDropDecoderInputUs(lateThresholdToDropDecoderInputUs);
if (Util.SDK_INT >= 34) {
if (SDK_INT >= 34) {
videoRendererBuilder =
videoRendererBuilder.experimentalSetEnableMediaCodecBufferDecodeOnlyFlag(
enableMediaCodecBufferDecodeOnlyFlag);
@ -889,7 +889,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
.setMaxDroppedFramesToNotify(MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY)
.experimentalSetParseAv1SampleDependencies(parseAv1SampleDependencies)
.experimentalSetLateThresholdToDropDecoderInputUs(lateThresholdToDropDecoderInputUs);
if (Util.SDK_INT >= 34) {
if (SDK_INT >= 34) {
builder =
builder.experimentalSetEnableMediaCodecBufferDecodeOnlyFlag(
enableMediaCodecBufferDecodeOnlyFlag);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkStateNotNull;
@ -48,9 +49,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Creates the default {@link SuitableOutputChecker}. */
public DefaultSuitableOutputChecker() {
if (Util.SDK_INT >= 35) {
if (SDK_INT >= 35) {
impl = new ImplApi35();
} else if (Util.SDK_INT >= 23) {
} else if (SDK_INT >= 23) {
impl = new ImplApi23();
} else {
impl = null;
@ -255,18 +256,18 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|| device.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
return true;
}
if (Util.SDK_INT >= 26 && device.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) {
if (SDK_INT >= 26 && device.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) {
return true;
}
if (Util.SDK_INT >= 28 && device.getType() == AudioDeviceInfo.TYPE_HEARING_AID) {
if (SDK_INT >= 28 && device.getType() == AudioDeviceInfo.TYPE_HEARING_AID) {
return true;
}
if (Util.SDK_INT >= 31
if (SDK_INT >= 31
&& (device.getType() == AudioDeviceInfo.TYPE_BLE_HEADSET
|| device.getType() == AudioDeviceInfo.TYPE_BLE_SPEAKER)) {
return true;
}
if (Util.SDK_INT >= 33 && device.getType() == AudioDeviceInfo.TYPE_BLE_BROADCAST) {
if (SDK_INT >= 33 && device.getType() == AudioDeviceInfo.TYPE_BLE_BROADCAST) {
return true;
}
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.C.AUDIO_SESSION_ID_UNSET;
import static androidx.media3.common.C.TRACK_TYPE_AUDIO;
import static androidx.media3.common.C.TRACK_TYPE_CAMERA_MOTION;
@ -394,7 +395,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
if (builder.foregroundModeTimeoutMs > 0) {
internalPlayer.experimentalSetForegroundModeTimeoutMs(builder.foregroundModeTimeoutMs);
}
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
Api31.registerMediaMetricsListener(
applicationContext, /* player= */ this, builder.usePlatformDiagnostics, playerId);
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.annotation.VisibleForTesting.NONE;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -45,7 +46,6 @@ import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.MediaFormatUtil;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSourceUtil;
import androidx.media3.datasource.DataSpec;
@ -1003,7 +1003,7 @@ public final class MediaExtractorCompat {
Format format = getFormat(scratchFormatHolder, scratchNoDataDecoderInputBuffer);
MediaFormat mediaFormatResult = MediaFormatUtil.createMediaFormatFromFormat(format);
if (compatibilityTrackMimeType != null) {
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
mediaFormatResult.removeKey(MediaFormat.KEY_CODECS_STRING);
}
mediaFormatResult.setString(MediaFormat.KEY_MIME, compatibilityTrackMimeType);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.annotation.SuppressLint;
@ -31,7 +32,6 @@ import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.BackgroundThreadStateHandler;
import androidx.media3.common.util.Clock;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** A manager that wraps {@link AudioManager} to control/listen audio stream volume. */
@ -247,7 +247,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
return state;
}
checkNotNull(audioManager);
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
audioManager.adjustStreamVolume(
state.streamType,
muted ? AudioManager.ADJUST_MUTE : AudioManager.ADJUST_UNMUTE,

View File

@ -764,7 +764,7 @@ public final class MediaMetricsListener
int subErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
int errorCode = getDrmErrorCode(subErrorCode);
return new ErrorInfo(errorCode, subErrorCode);
} else if (Util.SDK_INT >= 23 && cause instanceof MediaDrmResetException) {
} else if (cause instanceof MediaDrmResetException) {
return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_SYSTEM_ERROR, /* subErrorCode= */ 0);
} else if (cause instanceof NotProvisionedException) {
return new ErrorInfo(

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.analytics;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -22,7 +23,6 @@ import android.media.metrics.LogSessionId;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.ExoPlayer.Builder;
import java.util.Objects;
@ -55,7 +55,7 @@ public final class PlayerId {
*/
public PlayerId(String playerName) {
this.name = playerName;
this.logSessionIdApi31 = Util.SDK_INT >= 31 ? new LogSessionIdApi31() : null;
this.logSessionIdApi31 = SDK_INT >= 31 ? new LogSessionIdApi31() : null;
equalityToken = new Object();
}

View File

@ -16,6 +16,7 @@
package androidx.media3.exoplayer.audio;
import static android.media.AudioFormat.CHANNEL_OUT_STEREO;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static java.lang.Math.max;
@ -121,7 +122,7 @@ public final class AudioCapabilities {
Context context, AudioAttributes audioAttributes, @Nullable AudioDeviceInfo routedDevice) {
@Nullable
AudioDeviceInfoApi23 routedDeviceApi23 =
Util.SDK_INT >= 23 && routedDevice != null ? new AudioDeviceInfoApi23(routedDevice) : null;
SDK_INT >= 23 && routedDevice != null ? new AudioDeviceInfoApi23(routedDevice) : null;
return getCapabilitiesInternal(context, audioAttributes, routedDeviceApi23);
}
@ -147,11 +148,11 @@ public final class AudioCapabilities {
AudioDeviceInfoApi23 currentDevice =
routedDevice != null
? routedDevice
: Util.SDK_INT >= 33
: SDK_INT >= 33
? Api33.getDefaultRoutedDeviceForAttributes(audioManager, audioAttributes)
: null;
if (Util.SDK_INT >= 33 && (Util.isTv(context) || Util.isAutomotive(context))) {
if (SDK_INT >= 33 && (Util.isTv(context) || Util.isAutomotive(context))) {
// TV or automotive devices generally shouldn't support audio offload for surround encodings,
// so the encodings we get from AudioManager.getDirectProfilesForAttributes should include
// the PCM encodings and surround encodings for passthrough mode.
@ -160,7 +161,7 @@ public final class AudioCapabilities {
// If a connection to Bluetooth device is detected, we only return the minimum capabilities that
// is supported by all the devices.
if (Util.SDK_INT >= 23 && Api23.isBluetoothConnected(audioManager, currentDevice)) {
if (SDK_INT >= 23 && Api23.isBluetoothConnected(audioManager, currentDevice)) {
return DEFAULT_AUDIO_CAPABILITIES;
}
@ -171,7 +172,7 @@ public final class AudioCapabilities {
// offload, as well as for encodings we want to list for passthrough mode. Therefore we only use
// it on TV and automotive devices, which generally shouldn't support audio offload for surround
// encodings.
if (Util.SDK_INT >= 29 && (Util.isTv(context) || Util.isAutomotive(context))) {
if (SDK_INT >= 29 && (Util.isTv(context) || Util.isAutomotive(context))) {
supportedEncodings.addAll(Api29.getDirectPlaybackSupportedEncodings(audioAttributes));
return new AudioCapabilities(
getAudioProfiles(Ints.toArray(supportedEncodings.build()), DEFAULT_MAX_CHANNEL_COUNT));
@ -325,7 +326,7 @@ public final class AudioCapabilities {
audioProfile.getMaxSupportedChannelCountForPassthrough(sampleRate, audioAttributes);
} else {
channelCount = format.channelCount;
if (format.sampleMimeType.equals(MimeTypes.AUDIO_DTS_X) && Util.SDK_INT < 33) {
if (format.sampleMimeType.equals(MimeTypes.AUDIO_DTS_X) && SDK_INT < 33) {
// Some DTS:X TVs reports ACTION_HDMI_AUDIO_PLUG.EXTRA_MAX_CHANNEL_COUNT as 8
// instead of 10. See https://github.com/androidx/media/issues/396
if (channelCount > 10) {
@ -374,7 +375,7 @@ public final class AudioCapabilities {
}
private static int getChannelConfigForPassthrough(int channelCount) {
if (Util.SDK_INT <= 28) {
if (SDK_INT <= 28) {
// In passthrough mode the channel count used to configure the audio track doesn't affect how
// the stream is handled, except that some devices do overly-strict channel configuration
// checks. Therefore we override the channel count so that a known-working channel
@ -388,7 +389,7 @@ public final class AudioCapabilities {
// Workaround for Nexus Player not reporting support for mono passthrough. See
// [Internal: b/34268671].
if (Util.SDK_INT <= 26 && "fugu".equals(Build.DEVICE) && channelCount == 1) {
if (SDK_INT <= 26 && "fugu".equals(Build.DEVICE) && channelCount == 1) {
channelCount = 2;
}
@ -448,7 +449,7 @@ public final class AudioCapabilities {
private static final class AudioProfile {
public static final AudioProfile DEFAULT_AUDIO_PROFILE =
(Util.SDK_INT >= 33)
(SDK_INT >= 33)
? new AudioProfile(
C.ENCODING_PCM_16BIT,
getAllChannelMasksForMaxChannelCount(DEFAULT_MAX_CHANNEL_COUNT))
@ -492,7 +493,7 @@ public final class AudioCapabilities {
if (channelMasks != null) {
// We built the AudioProfile on API 33.
return maxChannelCount;
} else if (Util.SDK_INT >= 29) {
} else if (SDK_INT >= 29) {
return Api29.getMaxSupportedChannelCountForPassthrough(
encoding, sampleRate, audioAttributes);
}
@ -574,11 +575,11 @@ public final class AudioCapabilities {
ImmutableSet.Builder<Integer> allBluetoothDeviceTypes =
new ImmutableSet.Builder<Integer>()
.add(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, AudioDeviceInfo.TYPE_BLUETOOTH_SCO);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
allBluetoothDeviceTypes.add(
AudioDeviceInfo.TYPE_BLE_HEADSET, AudioDeviceInfo.TYPE_BLE_SPEAKER);
}
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
allBluetoothDeviceTypes.add(AudioDeviceInfo.TYPE_BLE_BROADCAST);
}
return allBluetoothDeviceTypes.build();
@ -594,7 +595,7 @@ public final class AudioCapabilities {
AudioAttributes audioAttributes) {
ImmutableList.Builder<Integer> supportedEncodingsListBuilder = ImmutableList.builder();
for (int encoding : ALL_SURROUND_ENCODINGS_AND_MAX_CHANNELS.keySet()) {
if (Util.SDK_INT < Util.getApiLevelThatAudioFormatIntroducedAudioEncoding(encoding)) {
if (SDK_INT < Util.getApiLevelThatAudioFormatIntroducedAudioEncoding(encoding)) {
// Example: AudioFormat.ENCODING_DTS_UHD_P2 is supported only from API 34.
continue;
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.content.BroadcastReceiver;
@ -91,7 +92,7 @@ public final class AudioCapabilitiesReceiver {
context,
listener,
audioAttributes,
Util.SDK_INT >= 23 && routedDevice != null ? new AudioDeviceInfoApi23(routedDevice) : null);
SDK_INT >= 23 && routedDevice != null ? new AudioDeviceInfoApi23(routedDevice) : null);
}
/* package */ AudioCapabilitiesReceiver(
@ -105,7 +106,7 @@ public final class AudioCapabilitiesReceiver {
this.audioAttributes = audioAttributes;
this.routedDevice = routedDevice;
handler = Util.createHandlerForCurrentOrMainLooper();
audioDeviceCallback = Util.SDK_INT >= 23 ? new AudioDeviceCallbackV23() : null;
audioDeviceCallback = SDK_INT >= 23 ? new AudioDeviceCallbackV23() : null;
hdmiAudioPlugBroadcastReceiver = new HdmiAudioPlugBroadcastReceiver();
Uri externalSurroundSoundUri = AudioCapabilities.getExternalSurroundSoundGlobalSettingUri();
externalSurroundSoundSettingObserver =
@ -159,7 +160,7 @@ public final class AudioCapabilitiesReceiver {
if (externalSurroundSoundSettingObserver != null) {
externalSurroundSoundSettingObserver.register();
}
if (Util.SDK_INT >= 23 && audioDeviceCallback != null) {
if (SDK_INT >= 23 && audioDeviceCallback != null) {
Api23.registerAudioDeviceCallback(context, audioDeviceCallback, handler);
}
Intent stickyIntent =
@ -183,7 +184,7 @@ public final class AudioCapabilitiesReceiver {
return;
}
audioCapabilities = null;
if (Util.SDK_INT >= 23 && audioDeviceCallback != null) {
if (SDK_INT >= 23 && audioDeviceCallback != null) {
Api23.unregisterAudioDeviceCallback(context, audioDeviceCallback);
}
context.unregisterReceiver(hdmiAudioPlugBroadcastReceiver);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.castNonNull;
import static androidx.media3.common.util.Util.durationUsToSampleCount;
@ -618,8 +619,7 @@ import java.lang.reflect.Method;
* b/18899620, b/19187573, b/21145353].
*/
private static boolean needsPassthroughWorkarounds(@C.Encoding int outputEncoding) {
return Util.SDK_INT < 23
&& (outputEncoding == C.ENCODING_AC3 || outputEncoding == C.ENCODING_E_AC3);
return SDK_INT < 23 && (outputEncoding == C.ENCODING_AC3 || outputEncoding == C.ENCODING_E_AC3);
}
private long getPlaybackHeadPositionUs() {
@ -679,7 +679,7 @@ import java.lang.reflect.Method;
rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
}
if (Util.SDK_INT <= 29) {
if (SDK_INT <= 29) {
if (rawPlaybackHeadPosition == 0
&& this.rawPlaybackHeadPosition > 0
&& state == PLAYSTATE_PLAYING) {

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_DRM_SESSION_CHANGED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_REUSE_NOT_IMPLEMENTED;
@ -762,7 +763,7 @@ public abstract class DecoderAudioRenderer<
audioSink.setAudioSessionId((Integer) message);
break;
case MSG_SET_PREFERRED_AUDIO_DEVICE:
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
Api23.setAudioSinkPreferredDevice(audioSink, message);
}
break;

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.content.Context;
@ -71,7 +72,7 @@ public final class DefaultAudioOffloadSupportProvider
checkNotNull(format);
checkNotNull(audioAttributes);
if (Util.SDK_INT < 29 || format.sampleRate == Format.NO_VALUE) {
if (SDK_INT < 29 || format.sampleRate == Format.NO_VALUE) {
return AudioOffloadSupport.DEFAULT_UNSUPPORTED;
}
@ -82,7 +83,7 @@ public final class DefaultAudioOffloadSupportProvider
@C.Encoding
int encoding = MimeTypes.getEncoding(checkNotNull(format.sampleMimeType), format.codecs);
if (encoding == C.ENCODING_INVALID
|| Util.SDK_INT < Util.getApiLevelThatAudioFormatIntroducedAudioEncoding(encoding)) {
|| SDK_INT < Util.getApiLevelThatAudioFormatIntroducedAudioEncoding(encoding)) {
// Example: AudioFormat.ENCODING_OPUS is supported only from API 30.
return AudioOffloadSupport.DEFAULT_UNSUPPORTED;
}
@ -99,7 +100,7 @@ public final class DefaultAudioOffloadSupportProvider
return AudioOffloadSupport.DEFAULT_UNSUPPORTED;
}
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
return Api31.getOffloadedPlaybackSupport(
audioFormat,
audioAttributes.getAudioAttributesV21().audioAttributes,
@ -165,8 +166,7 @@ public final class DefaultAudioOffloadSupportProvider
// (b/191950723) Gapless is not supported pre-API 33 due to playback position
// issue upon transition of gapless tracks
boolean isGaplessSupported =
Util.SDK_INT > 32
&& playbackOffloadSupport == AudioManager.PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED;
SDK_INT > 32 && playbackOffloadSupport == AudioManager.PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED;
return audioOffloadSupport
.setIsFormatSupported(true)
.setIsGaplessSupported(isGaplessSupported)

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Util.constrainValue;
@ -598,7 +599,7 @@ public final class DefaultAudioSink implements AudioSink {
audioCapabilities = context != null ? null : builder.audioCapabilities;
audioProcessorChain = builder.audioProcessorChain;
enableFloatOutput = builder.enableFloatOutput;
preferAudioTrackPlaybackParams = Util.SDK_INT >= 23 && builder.enableAudioTrackPlaybackParams;
preferAudioTrackPlaybackParams = SDK_INT >= 23 && builder.enableAudioTrackPlaybackParams;
offloadMode = OFFLOAD_MODE_DISABLED;
audioTrackBufferSizeProvider = builder.audioTrackBufferSizeProvider;
audioOffloadSupportProvider = checkNotNull(builder.audioOffloadSupportProvider);
@ -851,7 +852,7 @@ public final class DefaultAudioSink implements AudioSink {
configuration.inputFormat.encoderDelay, configuration.inputFormat.encoderPadding);
}
}
if (Util.SDK_INT >= 31 && playerId != null) {
if (SDK_INT >= 31 && playerId != null) {
Api31.setLogSessionIdOnAudioTrack(audioTrack, playerId);
}
audioSessionId = audioTrack.getAudioSessionId();
@ -867,13 +868,13 @@ public final class DefaultAudioSink implements AudioSink {
audioTrack.attachAuxEffect(auxEffectInfo.effectId);
audioTrack.setAuxEffectSendLevel(auxEffectInfo.sendLevel);
}
if (preferredDevice != null && Util.SDK_INT >= 23) {
if (preferredDevice != null && SDK_INT >= 23) {
Api23.setPreferredDeviceOnAudioTrack(audioTrack, preferredDevice);
if (audioCapabilitiesReceiver != null) {
audioCapabilitiesReceiver.setRoutedDevice(preferredDevice.audioDeviceInfo);
}
}
if (Util.SDK_INT >= 24 && audioCapabilitiesReceiver != null) {
if (SDK_INT >= 24 && audioCapabilitiesReceiver != null) {
onRoutingChangedListener =
new OnRoutingChangedListenerApi24(audioTrack, audioCapabilitiesReceiver);
}
@ -1358,7 +1359,7 @@ public final class DefaultAudioSink implements AudioSink {
}
private static boolean isAudioTrackDeadObject(int status) {
return (Util.SDK_INT >= 24 && status == AudioTrack.ERROR_DEAD_OBJECT)
return (SDK_INT >= 24 && status == AudioTrack.ERROR_DEAD_OBJECT)
|| status == ERROR_NATIVE_DEAD_OBJECT;
}
@ -1370,9 +1371,7 @@ public final class DefaultAudioSink implements AudioSink {
@Override
public boolean hasPendingData() {
return isAudioTrackInitialized()
&& (Util.SDK_INT < 29
|| !audioTrack.isOffloadedPlayback()
|| !handledOffloadOnPresentationEnded)
&& (SDK_INT < 29 || !audioTrack.isOffloadedPlayback() || !handledOffloadOnPresentationEnded)
&& audioTrackPositionTracker.hasPendingData(getWrittenFrames());
}
@ -1474,7 +1473,7 @@ public final class DefaultAudioSink implements AudioSink {
if (!isAudioTrackInitialized()) {
return C.TIME_UNSET;
}
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
return Api23.getAudioTrackBufferSizeUs(audioTrack, configuration);
}
long byteRate =
@ -1505,7 +1504,7 @@ public final class DefaultAudioSink implements AudioSink {
@RequiresApi(29)
@Override
public void setOffloadMode(@OffloadMode int offloadMode) {
Assertions.checkState(Util.SDK_INT >= 29);
Assertions.checkState(SDK_INT >= 29);
this.offloadMode = offloadMode;
}
@ -1560,7 +1559,7 @@ public final class DefaultAudioSink implements AudioSink {
pendingConfiguration = null;
}
audioTrackPositionTracker.reset();
if (Util.SDK_INT >= 24 && onRoutingChangedListener != null) {
if (SDK_INT >= 24 && onRoutingChangedListener != null) {
onRoutingChangedListener.release();
onRoutingChangedListener = null;
}
@ -1735,9 +1734,7 @@ public final class DefaultAudioSink implements AudioSink {
}
private boolean useAudioTrackPlaybackParams() {
return configuration != null
&& configuration.enableAudioTrackPlaybackParams
&& Util.SDK_INT >= 23;
return configuration != null && configuration.enableAudioTrackPlaybackParams && SDK_INT >= 23;
}
/**
@ -1841,7 +1838,7 @@ public final class DefaultAudioSink implements AudioSink {
}
private static boolean isOffloadedPlayback(AudioTrack audioTrack) {
return Util.SDK_INT >= 29 && audioTrack.isOffloadedPlayback();
return SDK_INT >= 29 && audioTrack.isOffloadedPlayback();
}
private static int getFramesPerEncodedSample(@C.Encoding int encoding, ByteBuffer buffer) {
@ -1902,7 +1899,7 @@ public final class DefaultAudioSink implements AudioSink {
private int writeNonBlockingWithAvSync(
AudioTrack audioTrack, ByteBuffer buffer, int size, long presentationTimeUs) {
if (Util.SDK_INT >= 26) {
if (SDK_INT >= 26) {
// The underlying platform AudioTrack writes AV sync headers directly.
return audioTrack.write(
buffer, size, AudioTrack.WRITE_NON_BLOCKING, presentationTimeUs * 1000);

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import android.media.AudioFormat;
import android.media.AudioTrack;
import androidx.annotation.RequiresApi;
@ -37,7 +39,7 @@ public class DefaultAudioTrackProvider implements DefaultAudioSink.AudioTrackPro
AudioSink.AudioTrackConfig audioTrackConfig,
AudioAttributes audioAttributes,
int audioSessionId) {
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
return createAudioTrackV23(audioTrackConfig, audioAttributes, audioSessionId);
} else {
return createAudioTrackV21(audioTrackConfig, audioAttributes, audioSessionId);
@ -61,7 +63,7 @@ public class DefaultAudioTrackProvider implements DefaultAudioSink.AudioTrackPro
.setTransferMode(AudioTrack.MODE_STREAM)
.setBufferSizeInBytes(audioTrackConfig.bufferSize)
.setSessionId(audioSessionId);
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
setOffloadedPlaybackV29(audioTrackBuilder, audioTrackConfig.offload);
}
return customizeAudioTrackBuilder(audioTrackBuilder).build();

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.REUSE_RESULT_NO;
@ -32,6 +33,7 @@ import android.media.MediaFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Pair;
import androidx.annotation.CallSuper;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
@ -43,6 +45,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.audio.AudioProcessor;
import androidx.media3.common.util.CodecSpecificDataUtil;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.MediaFormatUtil;
import androidx.media3.common.util.UnstableApi;
@ -264,7 +267,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
eventHandler,
eventListener,
audioSink,
Util.SDK_INT >= 35 ? new LoudnessCodecController() : null);
SDK_INT >= 35 ? new LoudnessCodecController() : null);
}
/**
@ -610,7 +613,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType)) {
// For PCM streams, the encoder passes through int samples despite set to float mode.
pcmEncoding = format.pcmEncoding;
} else if (Util.SDK_INT >= 24 && mediaFormat.containsKey(MediaFormat.KEY_PCM_ENCODING)) {
} else if (SDK_INT >= 24 && mediaFormat.containsKey(MediaFormat.KEY_PCM_ENCODING)) {
pcmEncoding = mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING);
} else if (mediaFormat.containsKey(VIVO_BITS_PER_SAMPLE_KEY)) {
pcmEncoding = Util.getPcmEncoding(mediaFormat.getInteger(VIVO_BITS_PER_SAMPLE_KEY));
@ -649,7 +652,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
}
}
try {
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
if (isBypassEnabled()
&& getConfiguration().offloadModePreferred != AudioSink.OFFLOAD_MODE_DISABLED) {
// TODO(b/280050553): Investigate potential issue where bypass is enabled for passthrough
@ -749,7 +752,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
protected void onRelease() {
audioSink.release();
if (Util.SDK_INT >= 35 && loudnessCodecController != null) {
if (SDK_INT >= 35 && loudnessCodecController != null) {
loudnessCodecController.release();
}
}
@ -908,7 +911,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
audioSink.setAuxEffectInfo(checkNotNull(auxEffectInfo));
break;
case MSG_SET_PREFERRED_AUDIO_DEVICE:
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
Api23.setAudioSinkPreferredDevice(audioSink, message);
}
break;
@ -930,7 +933,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
protected void handleInputBufferSupplementalData(DecoderInputBuffer buffer) {
if (Util.SDK_INT >= 29
if (SDK_INT >= 29
&& buffer.format != null
&& Objects.equals(buffer.format.sampleMimeType, MimeTypes.AUDIO_OPUS)
&& isBypassEnabled()) {
@ -983,7 +986,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
// Android TV running M, so there's no point requesting a non-default input size. Doing so may
// cause a native crash, whereas not doing so will cause a more controlled failure when
// attempting to fill an input buffer. See: https://github.com/google/ExoPlayer/issues/4057.
if (Util.SDK_INT < 24 && !(Util.SDK_INT == 23 && Util.isTv(context))) {
if (SDK_INT < 24 && !(SDK_INT == 23 && Util.isTv(context))) {
return Format.NO_VALUE;
}
}
@ -1013,27 +1016,34 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
// Set codec max values.
MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_MAX_INPUT_SIZE, codecMaxInputSize);
// Set codec configuration values.
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, 0 /* realtime priority */);
if (codecOperatingRate != CODEC_OPERATING_RATE_UNSET && !deviceDoesntSupportOperatingRate()) {
mediaFormat.setFloat(MediaFormat.KEY_OPERATING_RATE, codecOperatingRate);
}
}
if (Util.SDK_INT <= 28 && MimeTypes.AUDIO_AC4.equals(format.sampleMimeType)) {
if (MimeTypes.AUDIO_AC4.equals(format.sampleMimeType)) {
Pair<Integer, Integer> profileLevel = CodecSpecificDataUtil.getCodecProfileAndLevel(format);
if (profileLevel != null) {
MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_PROFILE, profileLevel.first);
MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_LEVEL, profileLevel.second);
}
if (SDK_INT <= 28) {
// On some older builds, the AC-4 decoder expects to receive samples formatted as raw frames
// not sync frames. Set a format key to override this.
mediaFormat.setInteger("ac4-is-sync", 1);
}
if (Util.SDK_INT >= 24
}
if (SDK_INT >= 24
&& audioSink.getFormatSupport(
Util.getPcmFormat(C.ENCODING_PCM_FLOAT, format.channelCount, format.sampleRate))
== AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY) {
mediaFormat.setInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_FLOAT);
}
if (Util.SDK_INT >= 32) {
if (SDK_INT >= 32) {
mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);
}
if (Util.SDK_INT >= 35) {
if (SDK_INT >= 35) {
mediaFormat.setInteger(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
}
return mediaFormat;
@ -1041,7 +1051,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
private void setAudioSessionId(int audioSessionId) {
audioSink.setAudioSessionId(audioSessionId);
if (Util.SDK_INT >= 35 && loudnessCodecController != null) {
if (SDK_INT >= 35 && loudnessCodecController != null) {
loudnessCodecController.setAudioSessionId(audioSessionId);
}
}
@ -1052,7 +1062,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
// If codec is null, then the importance will be set when initializing the codec.
return;
}
if (Util.SDK_INT >= 35) {
if (SDK_INT >= 35) {
Bundle codecParameters = new Bundle();
codecParameters.putInt(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
codec.setParameters(codecParameters);
@ -1077,8 +1087,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
* <p>See <a href="https://github.com/google/ExoPlayer/issues/5821">GitHub issue #5821</a>.
*/
private static boolean deviceDoesntSupportOperatingRate() {
return Util.SDK_INT == 23
&& ("ZTE B2017G".equals(Build.MODEL) || "AXON 7 mini".equals(Build.MODEL));
return SDK_INT == 23 && ("ZTE B2017G".equals(Build.MODEL) || "AXON 7 mini".equals(Build.MODEL));
}
/**
@ -1089,7 +1098,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
*/
private static boolean codecNeedsDiscardChannelsWorkaround(String codecName) {
// The workaround applies to Samsung Galaxy S6 and Samsung Galaxy S7.
return Util.SDK_INT < 24
return SDK_INT < 24
&& "OMX.SEC.aac.dec".equals(codecName)
&& "samsung".equals(Build.MANUFACTURER)
&& (Build.DEVICE.startsWith("zeroflte")

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.exoplayer.drm;
import static android.os.Build.VERSION.SDK_INT;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util;
import org.json.JSONArray;
@ -35,7 +37,7 @@ import org.json.JSONObject;
* @return The adjusted request data.
*/
public static byte[] adjustRequestData(byte[] request) {
if (Util.SDK_INT >= 27) {
if (SDK_INT >= 27) {
return request;
}
// Prior to O-MR1 the ClearKey CDM encoded the values in the "kids" array using Base64 encoding
@ -53,7 +55,7 @@ import org.json.JSONObject;
* @return The adjusted response data.
*/
public static byte[] adjustResponseData(byte[] response) {
if (Util.SDK_INT >= 27) {
if (SDK_INT >= 27) {
return response;
}
// Prior to O-MR1 the ClearKey CDM expected Base64 encoding rather than Base64Url encoding for

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.drm;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -593,7 +594,7 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
} else if (C.CENC_TYPE_cbcs.equals(schemeType)) {
// Support for cbcs (AES-CBC with pattern encryption) was added in API 24. However, the
// implementation was not stable until API 25.
return Util.SDK_INT >= 25;
return SDK_INT >= 25;
} else if (C.CENC_TYPE_cbc1.equals(schemeType) || C.CENC_TYPE_cens.equals(schemeType)) {
// Support for cbc1 (AES-CTR with pattern encryption) and cens (AES-CBC without pattern
// encryption) was also added in API 24 and made stable from API 25, however support was

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.drm;
import static android.os.Build.VERSION.SDK_INT;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
@ -90,7 +91,7 @@ public final class DrmUtil {
String diagnosticsInfo = ((MediaDrm.MediaDrmStateException) exception).getDiagnosticInfo();
int drmErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
return Util.getErrorCodeForMediaDrmErrorCode(drmErrorCode);
} else if (Util.SDK_INT >= 23 && Api23.isMediaDrmResetException(exception)) {
} else if (SDK_INT >= 23 && Api23.isMediaDrmResetException(exception)) {
return PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR;
} else if (exception instanceof NotProvisionedException
|| isFailureToConstructNotProvisionedException(exception)) {
@ -122,7 +123,7 @@ public final class DrmUtil {
* See b/291440132.
*/
public static boolean isFailureToConstructNotProvisionedException(@Nullable Throwable e) {
return Util.SDK_INT == 34
return SDK_INT == 34
&& e instanceof NoSuchMethodError
&& e.getMessage() != null
&& e.getMessage().contains("Landroid/media/NotProvisionedException;.<init>(");
@ -133,7 +134,7 @@ public final class DrmUtil {
* See b/291440132.
*/
public static boolean isFailureToConstructResourceBusyException(@Nullable Throwable e) {
return Util.SDK_INT == 34
return SDK_INT == 34
&& e instanceof NoSuchMethodError
&& e.getMessage() != null
&& e.getMessage().contains("Landroid/media/ResourceBusyException;.<init>(");

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.drm;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.annotation.SuppressLint;
@ -39,7 +40,6 @@ import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.ParsableByteArray;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.extractor.mp4.PsshAtomUtil;
import androidx.media3.extractor.mp4.PsshAtomUtil.PsshAtom;
@ -144,7 +144,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
@RequiresApi(23)
public void setOnKeyStatusChangeListener(
@Nullable ExoMediaDrm.OnKeyStatusChangeListener listener) {
if (Util.SDK_INT < 23) {
if (SDK_INT < 23) {
throw new UnsupportedOperationException();
}
@ -172,7 +172,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
@Override
@RequiresApi(23)
public void setOnExpirationUpdateListener(@Nullable OnExpirationUpdateListener listener) {
if (Util.SDK_INT < 23) {
if (SDK_INT < 23) {
throw new UnsupportedOperationException();
}
@ -199,7 +199,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
@UnstableApi
@Override
public void setPlayerIdForSession(byte[] sessionId, PlayerId playerId) {
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
try {
Api31.setLogSessionIdOnMediaDrmSession(mediaDrm, sessionId, playerId);
} catch (UnsupportedOperationException e) {
@ -238,8 +238,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
}
@KeyRequest.RequestType
int requestType =
Util.SDK_INT >= 23 ? request.getRequestType() : KeyRequest.REQUEST_TYPE_UNKNOWN;
int requestType = SDK_INT >= 23 ? request.getRequestType() : KeyRequest.REQUEST_TYPE_UNKNOWN;
return new KeyRequest(requestData, licenseServerUrl, requestType);
}
@ -248,7 +247,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
if (MOCK_LA_URL.equals(licenseServerUrl)) {
return "";
}
if (Util.SDK_INT >= 33 && "https://default.url".equals(licenseServerUrl)) {
if (SDK_INT >= 33 && "https://default.url".equals(licenseServerUrl)) {
// Work around b/247808112
String pluginVersion = getPropertyString("version");
if (Objects.equals(pluginVersion, "1.2") || Objects.equals(pluginVersion, "aidl-1")) {
@ -293,7 +292,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
@Override
public boolean requiresSecureDecoder(byte[] sessionId, String mimeType) {
boolean result;
if (Util.SDK_INT >= 31 && isMediaDrmRequiresSecureDecoderImplemented()) {
if (SDK_INT >= 31 && isMediaDrmRequiresSecureDecoderImplemented()) {
result =
Api31.requiresSecureDecoder(mediaDrm, mimeType, mediaDrm.getSecurityLevel(sessionId));
} else {
@ -341,7 +340,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
@UnstableApi
@RequiresApi(29)
public void removeOfflineLicense(byte[] keySetId) {
if (Util.SDK_INT < 29) {
if (SDK_INT < 29) {
throw new UnsupportedOperationException();
}
mediaDrm.removeOfflineLicense(keySetId);
@ -351,7 +350,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
@UnstableApi
@RequiresApi(29)
public List<byte[]> getOfflineLicenseKeySetIds() {
if (Util.SDK_INT < 29) {
if (SDK_INT < 29) {
throw new UnsupportedOperationException();
}
return mediaDrm.getOfflineLicenseKeySetIds();
@ -361,7 +360,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
@Override
@Nullable
public PersistableBundle getMetrics() {
if (Util.SDK_INT < 28) {
if (SDK_INT < 28) {
return null;
}
return mediaDrm.getMetrics();
@ -429,7 +428,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
return schemeDatas.get(0);
}
if (Util.SDK_INT >= 28 && schemeDatas.size() > 1) {
if (SDK_INT >= 28 && schemeDatas.size() > 1) {
// For API level 28 and above, concatenate multiple PSSH scheme datas if possible.
SchemeData firstSchemeData = schemeDatas.get(0);
int concatenatedDataLength = 0;
@ -466,9 +465,9 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
for (int i = 0; i < schemeDatas.size(); i++) {
SchemeData schemeData = schemeDatas.get(i);
int version = PsshAtomUtil.parseVersion(Assertions.checkNotNull(schemeData.data));
if (Util.SDK_INT < 23 && version == 0) {
if (SDK_INT < 23 && version == 0) {
return schemeData;
} else if (Util.SDK_INT >= 23 && version == 1) {
} else if (SDK_INT >= 23 && version == 1) {
return schemeData;
}
}
@ -508,7 +507,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
// that only provides V1 PSSH atoms. API levels 23 and above understand V0 and V1 PSSH atoms,
// and so we do not extract the data.
// Some Amazon devices also require data to be extracted from the PSSH atom for PlayReady.
if ((Util.SDK_INT < 23 && C.WIDEVINE_UUID.equals(uuid))
if ((SDK_INT < 23 && C.WIDEVINE_UUID.equals(uuid))
|| (C.PLAYREADY_UUID.equals(uuid)
&& "Amazon".equals(Build.MANUFACTURER)
&& ("AFTB".equals(Build.MODEL) // Fire TV Gen 1
@ -526,7 +525,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
private static String adjustRequestMimeType(UUID uuid, String mimeType) {
// Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
if (Util.SDK_INT < 26
if (SDK_INT < 26
&& C.CLEARKEY_UUID.equals(uuid)
&& (MimeTypes.VIDEO_MP4.equals(mimeType) || MimeTypes.AUDIO_MP4.equals(mimeType))) {
return CENC_SCHEME_MIME_TYPE;
@ -543,7 +542,7 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
private static boolean cdmRequiresCommonPsshUuid(UUID uuid) {
// ClearKey had to be accessed using the Common PSSH UUID prior to API level 27.
return Util.SDK_INT < 27 && Objects.equals(uuid, C.CLEARKEY_UUID);
return SDK_INT < 27 && Objects.equals(uuid, C.CLEARKEY_UUID);
}
private static void forceWidevineL3(MediaDrm mediaDrm) {

View File

@ -16,6 +16,7 @@
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.media.MediaCodec;
@ -35,7 +36,6 @@ import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.TraceUtil;
import androidx.media3.common.util.Util;
import androidx.media3.decoder.CryptoInfo;
import com.google.common.base.Supplier;
import java.io.IOException;
@ -129,7 +129,7 @@ import java.nio.ByteBuffer;
TraceUtil.endSection();
if (configuration.surface == null
&& configuration.codecInfo.detachedSurfaceSupported
&& Util.SDK_INT >= 35) {
&& SDK_INT >= 35) {
flags |= MediaCodec.CONFIGURE_FLAG_DETACHED_SURFACE;
}
codecAdapter.initialize(
@ -147,11 +147,11 @@ import java.nio.ByteBuffer;
@ChecksSdkIntAtLeast(api = 34)
private static boolean useSynchronousBufferQueueingWithAsyncCryptoFlag(Format format) {
if (Util.SDK_INT < 34) {
if (SDK_INT < 34) {
return false;
}
// CONFIGURE_FLAG_USE_CRYPTO_ASYNC only works for audio on API 35+ (see b/316565675).
return Util.SDK_INT >= 35 || MimeTypes.isVideo(format.sampleMimeType);
return SDK_INT >= 35 || MimeTypes.isVideo(format.sampleMimeType);
}
}
@ -198,7 +198,7 @@ import java.nio.ByteBuffer;
TraceUtil.beginSection("startCodec");
codec.start();
TraceUtil.endSection();
if (Util.SDK_INT >= 35 && loudnessCodecController != null) {
if (SDK_INT >= 35 && loudnessCodecController != null) {
loudnessCodecController.addMediaCodec(codec);
}
state = STATE_INITIALIZED;
@ -289,11 +289,11 @@ import java.nio.ByteBuffer;
// MediaCodec.release() returns too early before fully detaching a Surface, and a
// subsequent MediaCodec.configure() call using the same Surface then fails. See
// https://github.com/google/ExoPlayer/issues/8696 and b/191966399.
if (Util.SDK_INT >= 30 && Util.SDK_INT < 33) {
if (SDK_INT >= 30 && SDK_INT < 33) {
codec.stop();
}
} finally {
if (Util.SDK_INT >= 35 && loudnessCodecController != null) {
if (SDK_INT >= 35 && loudnessCodecController != null) {
loudnessCodecController.removeMediaCodec(codec);
}
codec.release();

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.annotation.VisibleForTesting.NONE;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.castNonNull;
@ -30,7 +31,6 @@ import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import androidx.media3.common.util.ConditionVariable;
import androidx.media3.common.util.NullableType;
import androidx.media3.common.util.Util;
import androidx.media3.decoder.CryptoInfo;
import java.util.ArrayDeque;
import java.util.Arrays;
@ -298,7 +298,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
frameworkCryptoInfo.key = checkNotNull(copy(cryptoInfo.key, frameworkCryptoInfo.key));
frameworkCryptoInfo.iv = checkNotNull(copy(cryptoInfo.iv, frameworkCryptoInfo.iv));
frameworkCryptoInfo.mode = cryptoInfo.mode;
if (Util.SDK_INT >= 24) {
if (SDK_INT >= 24) {
android.media.MediaCodec.CryptoInfo.Pattern pattern =
new android.media.MediaCodec.CryptoInfo.Pattern(
cryptoInfo.encryptedBlocks, cryptoInfo.clearBlocks);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.content.Context;
@ -146,7 +147,7 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
@Override
public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configuration)
throws IOException {
if (Util.SDK_INT >= 23
if (SDK_INT >= 23
&& (asynchronousMode == MODE_ENABLED
|| (asynchronousMode == MODE_DEFAULT && shouldUseAsynchronousAdapterInDefaultMode()))) {
int trackType = MimeTypes.getTrackType(configuration.format.sampleMimeType);
@ -166,14 +167,14 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
}
private boolean shouldUseAsynchronousAdapterInDefaultMode() {
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
// Asynchronous codec interactions started to be reliable for all devices on API 31+.
return true;
}
// Allow additional devices that work reliably with the asynchronous adapter and show
// performance problems when not using it.
if (context != null
&& Util.SDK_INT >= 28
&& SDK_INT >= 28
&& context.getPackageManager().hasSystemFeature("com.amazon.hardware.tv_screen")) {
return true;
}

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import android.media.MediaCodec;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
@ -43,7 +45,7 @@ public class MediaCodecDecoderException extends DecoderException {
? ((MediaCodec.CodecException) cause).getDiagnosticInfo()
: null;
errorCode =
Util.SDK_INT >= 23
SDK_INT >= 23
? getErrorCodeV23(cause)
: Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticInfo);
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_AUDIO_CHANNEL_COUNT_CHANGED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_AUDIO_ENCODING_CHANGED;
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_AUDIO_SAMPLE_RATE_CHANGED;
@ -247,7 +248,7 @@ public final class MediaCodecInfo {
* @see CodecCapabilities#getMaxSupportedInstances()
*/
public int getMaxSupportedInstances() {
if (Util.SDK_INT < 23 || capabilities == null) {
if (SDK_INT < 23 || capabilities == null) {
return MAX_SUPPORTED_INSTANCES_UNKNOWN;
}
return getMaxSupportedInstancesV23(capabilities);
@ -355,7 +356,7 @@ public final class MediaCodecInfo {
}
CodecProfileLevel[] profileLevels = getProfileLevels();
if (Util.SDK_INT <= 23 && MimeTypes.VIDEO_VP9.equals(mimeType) && profileLevels.length == 0) {
if (SDK_INT <= 23 && MimeTypes.VIDEO_VP9.equals(mimeType) && profileLevels.length == 0) {
// Some older devices don't report profile levels for VP9. Estimate them using other data in
// the codec capabilities.
profileLevels = estimateLegacyVp9ProfileLevels(capabilities);
@ -379,13 +380,13 @@ public final class MediaCodecInfo {
// exists.
return !Objects.equals(format.sampleMimeType, MimeTypes.AUDIO_FLAC)
|| format.pcmEncoding != C.ENCODING_PCM_32BIT
|| Util.SDK_INT >= 34
|| SDK_INT >= 34
|| !name.equals("c2.android.flac.decoder");
}
/** Whether the codec handles HDR10+ out-of-band metadata. */
public boolean isHdr10PlusOutOfBandMetadataSupported() {
if (Util.SDK_INT >= 29 && MimeTypes.VIDEO_VP9.equals(mimeType)) {
if (SDK_INT >= 29 && MimeTypes.VIDEO_VP9.equals(mimeType)) {
for (CodecProfileLevel capabilities : getProfileLevels()) {
if (capabilities.profile == CodecProfileLevel.VP9Profile2HDR10Plus) {
return true;
@ -531,7 +532,7 @@ public final class MediaCodecInfo {
return false;
}
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
@MediaCodecPerformancePointCoverageProvider.PerformancePointCoverageResult
int evaluation =
MediaCodecPerformancePointCoverageProvider.areResolutionAndFrameRateCovered(
@ -657,7 +658,7 @@ public final class MediaCodecInfo {
}
private static int adjustMaxInputChannelCount(String name, String mimeType, int maxChannelCount) {
if (maxChannelCount > 1 || (Util.SDK_INT >= 26 && maxChannelCount > 0)) {
if (maxChannelCount > 1 || (SDK_INT >= 26 && maxChannelCount > 0)) {
// The maximum channel count looks like it's been set correctly.
return maxChannelCount;
}
@ -710,7 +711,7 @@ public final class MediaCodecInfo {
}
private static boolean isDetachedSurfaceSupported(@Nullable CodecCapabilities capabilities) {
return Util.SDK_INT >= 35
return SDK_INT >= 35
&& capabilities != null
&& capabilities.isFeatureSupported(CodecCapabilities.FEATURE_DetachedSurface)
&& !needsDetachedSurfaceUnsupportedWorkaround();
@ -735,7 +736,7 @@ public final class MediaCodecInfo {
if (!capabilities.areSizeAndRateSupported(width, height, floorFrameRate)) {
return false;
}
if (Util.SDK_INT < 24) {
if (SDK_INT < 24) {
return true;
}
@Nullable
@ -761,8 +762,8 @@ public final class MediaCodecInfo {
}
/**
* Called on devices with {@link Util#SDK_INT} 23 and below, for VP9 decoders whose {@link
* CodecCapabilities} do not correctly report profile levels. The returned {@link
* Called on devices with {@link Build.VERSION#SDK_INT} 23 and below, for VP9 decoders whose
* {@link CodecCapabilities} do not correctly report profile levels. The returned {@link
* CodecProfileLevel CodecProfileLevels} are estimated based on other data in the {@link
* CodecCapabilities}.
*
@ -818,7 +819,7 @@ public final class MediaCodecInfo {
* @return True if the decoder is known to fail when adapting.
*/
private static boolean needsDisableAdaptationWorkaround(String name) {
return Util.SDK_INT <= 22
return SDK_INT <= 22
&& ("ODROID-XU3".equals(Build.MODEL) || "Nexus 10".equals(Build.MODEL))
&& ("OMX.Exynos.AVC.Decoder".equals(name) || "OMX.Exynos.AVC.Decoder.secure".equals(name));
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.media.MediaCodecInfo.VideoCapabilities;
@ -23,7 +24,6 @@ import androidx.annotation.IntDef;
import androidx.annotation.RequiresApi;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Util;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -85,8 +85,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
*/
public static @PerformancePointCoverageResult int areResolutionAndFrameRateCovered(
VideoCapabilities videoCapabilities, int width, int height, double frameRate) {
if (Util.SDK_INT < 29
|| (shouldIgnorePerformancePoints != null && shouldIgnorePerformancePoints)) {
if (SDK_INT < 29 || (shouldIgnorePerformancePoints != null && shouldIgnorePerformancePoints)) {
return COVERAGE_RESULT_NO_PERFORMANCE_POINTS_UNSUPPORTED;
}
@ -131,7 +130,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* Checks if the CDD-requirement to support H264 720p at 60 fps is covered by PerformancePoints.
*/
private static boolean shouldIgnorePerformancePoints() {
if (Util.SDK_INT >= 35) {
if (SDK_INT >= 35) {
// The same check as below is tested in CTS and we should get reliable results from API 35.
return false;
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Assertions.checkStateNotNull;
@ -945,9 +946,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return true;
}
if (codecDrainAction == DRAIN_ACTION_FLUSH_AND_UPDATE_DRM_SESSION) {
checkState(Util.SDK_INT >= 23); // Implied by DRAIN_ACTION_FLUSH_AND_UPDATE_DRM_SESSION
checkState(SDK_INT >= 23); // Implied by DRAIN_ACTION_FLUSH_AND_UPDATE_DRM_SESSION
// Needed to keep lint happy (it doesn't understand the checkState call alone)
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
try {
updateDrmSessionV23();
} catch (ExoPlaybackException e) {
@ -1215,7 +1216,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
long codecInitializedTimestamp;
String codecName = codecInfo.name;
float codecOperatingRate =
Util.SDK_INT < 23
SDK_INT < 23
? CODEC_OPERATING_RATE_UNSET
: getCodecOperatingRateV23(targetPlaybackSpeed, inputFormat, getStreamFormats());
if (codecOperatingRate <= assumedMinimumCodecOperatingRate) {
@ -1224,7 +1225,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecInitializingTimestamp = getClock().elapsedRealtime();
MediaCodecAdapter.Configuration configuration =
getMediaCodecConfiguration(codecInfo, inputFormat, crypto, codecOperatingRate);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
Api31.setLogSessionIdToMediaCodecFormat(configuration, getPlayerId());
}
try {
@ -1610,7 +1611,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
DISCARD_REASON_DRM_SESSION_CHANGED);
}
boolean drainAndUpdateCodecDrmSession = sourceDrmSession != codecDrmSession;
Assertions.checkState(!drainAndUpdateCodecDrmSession || Util.SDK_INT >= 23);
Assertions.checkState(!drainAndUpdateCodecDrmSession || SDK_INT >= 23);
DecoderReuseEvaluation evaluation = canReuseCodec(codecInfo, oldFormat, newFormat);
@DecoderDiscardReasons int overridingDiscardReasons = 0;
@ -1899,7 +1900,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* @return False if codec release and re-initialization was triggered. True in all other cases.
*/
private boolean updateCodecOperatingRate(@Nullable Format format) throws ExoPlaybackException {
if (Util.SDK_INT < 23) {
if (SDK_INT < 23) {
return true;
}
@ -2323,7 +2324,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return true;
}
if (Util.SDK_INT < 23) {
if (SDK_INT < 23) {
// MediaCrypto.setMediaDrmSession is only available from API level 23, so re-initialization is
// required to switch to newSession on older API levels.
return true;
@ -2572,14 +2573,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* @return The mode specifying when the adaptation workaround should be enabled.
*/
private @AdaptationWorkaroundMode int codecAdaptationWorkaroundMode(String name) {
if (Util.SDK_INT <= 25
if (SDK_INT <= 25
&& "OMX.Exynos.avc.dec.secure".equals(name)
&& (Build.MODEL.startsWith("SM-T585")
|| Build.MODEL.startsWith("SM-A510")
|| Build.MODEL.startsWith("SM-A520")
|| Build.MODEL.startsWith("SM-J700"))) {
return ADAPTATION_WORKAROUND_MODE_ALWAYS;
} else if (Util.SDK_INT < 24
} else if (SDK_INT < 24
&& ("OMX.Nvidia.h264.decode".equals(name) || "OMX.Nvidia.h264.decode.secure".equals(name))
&& ("flounder".equals(Build.DEVICE)
|| "flounder_lte".equals(Build.DEVICE)
@ -2605,7 +2606,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* {@link MediaFormat}. False otherwise.
*/
private static boolean codecNeedsSosFlushWorkaround(String name) {
return Util.SDK_INT == 29 && "c2.android.aac.decoder".equals(name);
return SDK_INT == 29 && "c2.android.aac.decoder".equals(name);
}
/**
@ -2622,8 +2623,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
*/
private static boolean codecNeedsEosPropagationWorkaround(MediaCodecInfo codecInfo) {
String name = codecInfo.name;
return (Util.SDK_INT <= 25 && "OMX.rk.video_decoder.avc".equals(name))
|| (Util.SDK_INT <= 29
return (SDK_INT <= 25 && "OMX.rk.video_decoder.avc".equals(name))
|| (SDK_INT <= 29
&& ("OMX.broadcom.video_decoder.tunnel".equals(name)
|| "OMX.broadcom.video_decoder.tunnel.secure".equals(name)
|| "OMX.bcm.vdec.avc.tunnel".equals(name)
@ -2647,7 +2648,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* buffer with {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM} set. False otherwise.
*/
private static boolean codecNeedsEosFlushWorkaround(String name) {
return Util.SDK_INT <= 23 && "OMX.google.vorbis.decoder".equals(name);
return SDK_INT <= 23 && "OMX.google.vorbis.decoder".equals(name);
}
/**
@ -2662,7 +2663,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* @return True if the decoder may throw an exception after receiving an end-of-stream buffer.
*/
private static boolean codecNeedsEosOutputExceptionWorkaround(String name) {
return Util.SDK_INT == 21 && "OMX.google.aac.decoder".equals(name);
return SDK_INT == 21 && "OMX.google.aac.decoder".equals(name);
}
private static final class OutputStreamInfo {

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.CodecSpecificDataUtil.getHevcProfileAndLevel;
import static java.lang.Math.max;
@ -158,7 +159,7 @@ public final class MediaCodecUtil {
MediaCodecListCompat mediaCodecList =
new MediaCodecListCompatV21(secure, tunneling, specialCodec);
ArrayList<MediaCodecInfo> decoderInfos = getDecoderInfosInternal(key, mediaCodecList);
if (secure && decoderInfos.isEmpty() && Util.SDK_INT <= 23) {
if (secure && decoderInfos.isEmpty() && SDK_INT <= 23) {
// Some devices don't list secure decoders on API level 21 [Internal: b/18678462]. Try the
// legacy path. We also try this path on API levels 22 and 23 as a defensive measure.
mediaCodecList = new MediaCodecListCompatV16();
@ -490,7 +491,7 @@ public final class MediaCodecUtil {
return decoderInfos;
}
} catch (Exception e) {
if (Util.SDK_INT <= 23 && !decoderInfos.isEmpty()) {
if (SDK_INT <= 23 && !decoderInfos.isEmpty()) {
// Suppress error querying secondary codec capabilities up to API level 23.
Log.e(TAG, "Skipping codec " + name + " (failed to query capabilities)");
} else {
@ -574,7 +575,7 @@ public final class MediaCodecUtil {
}
// Work around https://github.com/google/ExoPlayer/issues/3249.
if (Util.SDK_INT < 24
if (SDK_INT < 24
&& ("OMX.SEC.aac.dec".equals(name) || "OMX.Exynos.AAC.Decoder".equals(name))
&& "samsung".equals(Build.MANUFACTURER)
&& (Build.DEVICE.startsWith("zeroflte") // Galaxy S6
@ -589,7 +590,7 @@ public final class MediaCodecUtil {
}
// MTK AC3 decoder doesn't support decoding JOC streams in 2-D. See [Internal: b/69400041].
if (Util.SDK_INT <= 23
if (SDK_INT <= 23
&& MimeTypes.AUDIO_E_AC3_JOC.equals(mimeType)
&& "OMX.MTK.AUDIO.DECODER.DSPAC3".equals(name)) {
return false;
@ -607,7 +608,7 @@ public final class MediaCodecUtil {
*/
private static void applyWorkarounds(String mimeType, List<MediaCodecInfo> decoderInfos) {
if (MimeTypes.AUDIO_RAW.equals(mimeType)) {
if (Util.SDK_INT < 26
if (SDK_INT < 26
&& Build.DEVICE.equals("R9")
&& decoderInfos.size() == 1
&& decoderInfos.get(0).name.equals("OMX.MTK.AUDIO.DECODER.RAW")) {
@ -634,7 +635,7 @@ public final class MediaCodecUtil {
// Prefer generic decoders over ones provided by the device.
return 1;
}
if (Util.SDK_INT < 26 && name.equals("OMX.MTK.AUDIO.DECODER.RAW")) {
if (SDK_INT < 26 && name.equals("OMX.MTK.AUDIO.DECODER.RAW")) {
// This decoder may modify the audio, so any other compatible decoders take
// precedence. See [Internal: b/62337687].
return -1;
@ -643,7 +644,7 @@ public final class MediaCodecUtil {
});
}
if (Util.SDK_INT < 32 && decoderInfos.size() > 1) {
if (SDK_INT < 32 && decoderInfos.size() > 1) {
String firstCodecName = decoderInfos.get(0).name;
// Prefer anything other than OMX.qti.audio.decoder.flac on older devices. See [Internal
// ref: b/199124812].
@ -654,7 +655,7 @@ public final class MediaCodecUtil {
}
private static boolean isAlias(android.media.MediaCodecInfo info) {
return Util.SDK_INT >= 29 && isAliasV29(info);
return SDK_INT >= 29 && isAliasV29(info);
}
@RequiresApi(29)
@ -668,7 +669,7 @@ public final class MediaCodecUtil {
*/
private static boolean isHardwareAccelerated(
android.media.MediaCodecInfo codecInfo, String mimeType) {
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
return isHardwareAcceleratedV29(codecInfo);
}
// codecInfo.isHardwareAccelerated() != codecInfo.isSoftwareOnly() is not necessarily true.
@ -686,7 +687,7 @@ public final class MediaCodecUtil {
* best-effort approximation for lower levels.
*/
private static boolean isSoftwareOnly(android.media.MediaCodecInfo codecInfo, String mimeType) {
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
return isSoftwareOnlyV29(codecInfo);
}
if (MimeTypes.isAudio(mimeType)) {
@ -717,7 +718,7 @@ public final class MediaCodecUtil {
* best-effort approximation for lower levels.
*/
private static boolean isVendor(android.media.MediaCodecInfo codecInfo) {
if (Util.SDK_INT >= 29) {
if (SDK_INT >= 29) {
return isVendorV29(codecInfo);
}
String codecName = Ascii.toLowerCase(codecInfo.getName());

View File

@ -16,6 +16,7 @@
package androidx.media3.exoplayer.mediacodec;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.annotation.SuppressLint;
@ -30,7 +31,6 @@ import androidx.annotation.RequiresApi;
import androidx.media3.common.C;
import androidx.media3.common.util.TraceUtil;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.decoder.CryptoInfo;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -54,7 +54,7 @@ public final class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
int flags = 0;
if (configuration.surface == null
&& configuration.codecInfo.detachedSurfaceSupported
&& Util.SDK_INT >= 35) {
&& SDK_INT >= 35) {
flags |= MediaCodec.CONFIGURE_FLAG_DETACHED_SURFACE;
}
codec.configure(
@ -90,7 +90,7 @@ public final class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
MediaCodec mediaCodec, @Nullable LoudnessCodecController loudnessCodecController) {
this.codec = mediaCodec;
this.loudnessCodecController = loudnessCodecController;
if (Util.SDK_INT >= 35 && loudnessCodecController != null) {
if (SDK_INT >= 35 && loudnessCodecController != null) {
loudnessCodecController.addMediaCodec(codec);
}
}
@ -163,7 +163,7 @@ public final class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
@Override
public void release() {
try {
if (Util.SDK_INT >= 30 && Util.SDK_INT < 33) {
if (SDK_INT >= 30 && SDK_INT < 33) {
// Stopping the codec before releasing it works around a bug on APIs 30, 31 and 32 where
// MediaCodec.release() returns too early before fully detaching a Surface, and a
// subsequent MediaCodec.configure() call using the same Surface then fails. See
@ -171,7 +171,7 @@ public final class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
codec.stop();
}
} finally {
if (Util.SDK_INT >= 35 && loudnessCodecController != null) {
if (SDK_INT >= 35 && loudnessCodecController != null) {
loudnessCodecController.removeMediaCodec(codec);
}
codec.release();

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.offline;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE;
import android.annotation.SuppressLint;
@ -28,7 +29,6 @@ import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.media3.common.C;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.R;
import androidx.media3.exoplayer.scheduler.Requirements;
import java.util.List;
@ -227,7 +227,7 @@ public final class DownloadNotificationHelper {
notificationBuilder.setProgress(maxProgress, currentProgress, indeterminateProgress);
notificationBuilder.setOngoing(ongoing);
notificationBuilder.setShowWhen(showWhen);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
Api31.setForegroundServiceBehavior(notificationBuilder);
}
return notificationBuilder.build();

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.offline;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.exoplayer.offline.Download.STOP_REASON_NONE;
import android.annotation.SuppressLint;
@ -595,7 +596,7 @@ public abstract class DownloadService extends Service {
if (downloadManagerHelper == null) {
boolean foregroundAllowed = foregroundNotificationUpdater != null;
// See https://developer.android.com/about/versions/12/foreground-services.
boolean canStartForegroundServiceFromBackground = Util.SDK_INT < 31;
boolean canStartForegroundServiceFromBackground = SDK_INT < 31;
@Nullable
Scheduler scheduler =
foregroundAllowed && canStartForegroundServiceFromBackground ? getScheduler() : null;
@ -683,7 +684,7 @@ public abstract class DownloadService extends Service {
break;
}
if (Util.SDK_INT >= 26 && startedInForeground && foregroundNotificationUpdater != null) {
if (SDK_INT >= 26 && startedInForeground && foregroundNotificationUpdater != null) {
// From API level 26, services started in the foreground are required to show a notification.
foregroundNotificationUpdater.showNotificationIfNotAlready();
}
@ -844,7 +845,7 @@ public abstract class DownloadService extends Service {
// Stop the service, either because the DownloadManager is not waiting for requirements to be
// met, or because we've scheduled the service to be restarted when they are.
if (Util.SDK_INT < 28 && taskRemoved) { // See [Internal: b/74248644].
if (SDK_INT < 28 && taskRemoved) { // See [Internal: b/74248644].
stopSelf();
isStopped = true;
} else {

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.scheduler;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.app.job.JobInfo;
@ -55,7 +56,7 @@ public final class PlatformScheduler implements Scheduler {
| Requirements.NETWORK_UNMETERED
| Requirements.DEVICE_IDLE
| Requirements.DEVICE_CHARGING
| (Util.SDK_INT >= 26 ? Requirements.DEVICE_STORAGE_NOT_LOW : 0);
| (SDK_INT >= 26 ? Requirements.DEVICE_STORAGE_NOT_LOW : 0);
private final int jobId;
private final ComponentName jobServiceComponentName;
@ -120,7 +121,7 @@ public final class PlatformScheduler implements Scheduler {
}
builder.setRequiresDeviceIdle(requirements.isIdleRequired());
builder.setRequiresCharging(requirements.isChargingRequired());
if (Util.SDK_INT >= 26 && requirements.isStorageNotLowRequired()) {
if (SDK_INT >= 26 && requirements.isStorageNotLowRequired()) {
builder.setRequiresStorageNotLow(true);
}
builder.setPersisted(true);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.scheduler;
import static android.os.Build.VERSION.SDK_INT;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
@ -36,7 +37,6 @@ import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -202,7 +202,7 @@ public final class Requirements implements Parcelable {
private boolean isDeviceIdle(Context context) {
PowerManager powerManager =
(PowerManager) Assertions.checkNotNull(context.getSystemService(Context.POWER_SERVICE));
return Util.SDK_INT >= 23 ? powerManager.isDeviceIdleMode() : !powerManager.isInteractive();
return SDK_INT >= 23 ? powerManager.isDeviceIdleMode() : !powerManager.isInteractive();
}
private boolean isStorageNotLow(Context context) {
@ -216,7 +216,7 @@ public final class Requirements implements Parcelable {
// RequirementsWatcher only fires an event to re-check the requirements when NetworkCapabilities
// change from API level 24. We assume that network capability is validated for API level 23 to
// keep in sync.
if (Util.SDK_INT < 24) {
if (SDK_INT < 24) {
return true;
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.scheduler;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.content.BroadcastReceiver;
@ -88,7 +89,7 @@ public final class RequirementsWatcher {
IntentFilter filter = new IntentFilter();
if (requirements.isNetworkRequired()) {
if (Util.SDK_INT >= 24) {
if (SDK_INT >= 24) {
registerNetworkCallbackV24();
} else {
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
@ -99,7 +100,7 @@ public final class RequirementsWatcher {
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
}
if (requirements.isIdleRequired()) {
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
} else {
filter.addAction(Intent.ACTION_SCREEN_ON);
@ -119,7 +120,7 @@ public final class RequirementsWatcher {
public void stop() {
context.unregisterReceiver(checkNotNull(receiver));
receiver = null;
if (Util.SDK_INT >= 24 && networkCallback != null) {
if (SDK_INT >= 24 && networkCallback != null) {
unregisterNetworkCallbackV24();
}
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.source;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_EAGERLY_EXPOSE_TRACK_TYPE;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_INCLUDE_SUPPLEMENTAL_DATA;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_IN_BAND_CRYPTO_INFO;
@ -28,7 +29,6 @@ import androidx.annotation.RequiresApi;
import androidx.media3.common.C;
import androidx.media3.common.DataReader;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.source.mediaparser.InputReaderAdapterV30;
import androidx.media3.exoplayer.source.mediaparser.MediaParserUtil;
@ -107,7 +107,7 @@ public final class MediaParserExtractorAdapter implements ProgressiveMediaExtrac
mediaParser.setParameter(parameter.getKey(), parameter.getValue());
}
parserName = MediaParser.PARSER_NAME_UNKNOWN;
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
MediaParserUtil.setLogSessionIdOnMediaParser(mediaParser, playerId);
}
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.source.chunk;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_EAGERLY_EXPOSE_TRACK_TYPE;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_EXPOSE_CAPTION_FORMATS;
@ -34,7 +35,6 @@ import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.source.mediaparser.InputReaderAdapterV30;
import androidx.media3.exoplayer.source.mediaparser.MediaParserUtil;
@ -196,7 +196,7 @@ public final class MediaParserChunkExtractor implements ChunkExtractor {
MediaParserUtil.toCaptionsMediaFormat(closedCaptionFormats.get(i)));
}
mediaParser.setParameter(PARAMETER_EXPOSE_CAPTION_FORMATS, closedCaptionMediaFormats);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
MediaParserUtil.setLogSessionIdOnMediaParser(mediaParser, playerId);
}
outputConsumerAdapter.setMuxedCaptionFormats(closedCaptionFormats);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.trackselection;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_DISABLED;
import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_REQUIRED;
import static androidx.media3.common.util.Assertions.checkNotNull;
@ -2482,7 +2483,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
@Override
public void release() {
if (Util.SDK_INT >= 32 && spatializer != null) {
if (SDK_INT >= 32 && spatializer != null) {
spatializer.release();
}
super.release();
@ -2592,7 +2593,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
parameters = this.parameters;
}
if (parameters.constrainAudioChannelCountToDeviceCapabilities
&& Util.SDK_INT >= 32
&& SDK_INT >= 32
&& spatializer == null) {
spatializer = new SpatializerWrapperV32(context, /* defaultTrackSelector= */ this);
}
@ -2868,10 +2869,8 @@ public class DefaultTrackSelector extends MappingTrackSelector
return !parameters.constrainAudioChannelCountToDeviceCapabilities
|| (format.channelCount == Format.NO_VALUE || format.channelCount <= 2)
|| (isDolbyAudio(format)
&& (Util.SDK_INT < 32
|| spatializer == null
|| !spatializer.isSpatializationSupported()))
|| (Util.SDK_INT >= 32
&& (SDK_INT < 32 || spatializer == null || !spatializer.isSpatializationSupported()))
|| (SDK_INT >= 32
&& spatializer != null
&& spatializer.isSpatializationSupported()
&& spatializer.isAvailable()
@ -3065,7 +3064,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
synchronized (lock) {
shouldInvalidate =
parameters.constrainAudioChannelCountToDeviceCapabilities
&& Util.SDK_INT >= 32
&& SDK_INT >= 32
&& spatializer != null
&& spatializer.isSpatializationSupported();
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.video;
import static android.os.Build.VERSION.SDK_INT;
import static android.view.Display.DEFAULT_DISPLAY;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -764,7 +765,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
@DecoderSupport
int decoderSupport = isPreferredDecoder ? DECODER_SUPPORT_PRIMARY : DECODER_SUPPORT_FALLBACK;
if (Util.SDK_INT >= 26
if (SDK_INT >= 26
&& MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)
&& !Api26.doesDisplaySupportDolbyVision(context)) {
decoderSupport = DECODER_SUPPORT_FALLBACK_MIMETYPE;
@ -835,7 +836,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (format.sampleMimeType == null) {
return ImmutableList.of();
}
if (Util.SDK_INT >= 26
if (SDK_INT >= 26
&& MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)
&& !Api26.doesDisplaySupportDolbyVision(context)) {
List<MediaCodecInfo> alternativeDecoderInfos =
@ -982,6 +983,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
Context context, VideoFrameReleaseControl videoFrameReleaseControl) {
// TODO: b/391109644 - Add a more explicit API to enable replaying.
return new PlaybackVideoGraphWrapper.Builder(context, videoFrameReleaseControl)
.setEnablePlaylistMode(true)
.setClock(getClock())
.build();
}
@ -1214,7 +1216,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (codec != null && videoSink == null) {
MediaCodecInfo codecInfo = checkNotNull(getCodecInfo());
boolean canUpdateSurface = hasSurfaceForCodec(codecInfo);
if (Util.SDK_INT >= 23 && canUpdateSurface && !codecNeedsSetOutputSurfaceWorkaround) {
if (SDK_INT >= 23 && canUpdateSurface && !codecNeedsSetOutputSurfaceWorkaround) {
setOutputSurface(codec, getSurfaceForCodec(codecInfo));
} else {
releaseCodec();
@ -1259,7 +1261,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
@Override
protected boolean getCodecNeedsEosPropagation() {
// Since API 23, onFrameRenderedListener allows for detection of the renderer EOS.
return tunneling && Util.SDK_INT < 23;
return tunneling && SDK_INT < 23;
}
@Override
@ -1525,7 +1527,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (!tunneling) {
buffersInCodecCount++;
}
if (Util.SDK_INT < 23 && tunneling) {
if (SDK_INT < 23 && tunneling) {
// In tunneled mode before API 23 we don't have a way to know when the buffer is output, so
// treat it as if it were output immediately.
onProcessedTunneledBuffer(buffer.timeUs);
@ -1534,7 +1536,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
@Override
protected int getCodecBufferFlags(DecoderInputBuffer buffer) {
if (Util.SDK_INT >= 34
if (SDK_INT >= 34
&& (enableMediaCodecBufferDecodeOnlyFlag || tunneling)
&& isBufferBeforeStartTime(buffer)) {
// The buffer likely needs to be dropped because its timestamp is less than the start time.
@ -2146,11 +2148,11 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
}
protected boolean shouldUseDetachedSurface(MediaCodecInfo codecInfo) {
return Util.SDK_INT >= 35 && codecInfo.detachedSurfaceSupported;
return SDK_INT >= 35 && codecInfo.detachedSurfaceSupported;
}
protected boolean shouldUsePlaceholderSurface(MediaCodecInfo codecInfo) {
return Util.SDK_INT >= 23
return SDK_INT >= 23
&& !tunneling
&& !codecNeedsSetOutputSurfaceWorkaround(codecInfo.name)
&& (!codecInfo.secure || PlaceholderSurface.isSecureSupported(context));
@ -2164,7 +2166,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
}
private void maybeSetupTunnelingForFirstFrame() {
if (!tunneling || Util.SDK_INT < 23) {
if (!tunneling || SDK_INT < 23) {
// The first frame notification for tunneling is triggered by onQueueInputBuffer prior to API
// level 23 and no setup is needed here.
return;
@ -2175,7 +2177,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
return;
}
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
// This should be the default anyway according to the API contract, but some devices are known
// to not adhere to this contract and need to get the parameter explicitly. See
// https://github.com/androidx/media/issues/1169.
@ -2191,7 +2193,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
// If codec is null, then the importance will be set when initializing the codec.
return;
}
if (Util.SDK_INT >= 35) {
if (SDK_INT >= 35) {
Bundle codecParameters = new Bundle();
codecParameters.putInt(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
codec.setParameters(codecParameters);
@ -2257,9 +2259,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
}
private void setOutputSurface(MediaCodecAdapter codec, @Nullable Surface surface) {
if (Util.SDK_INT >= 23 && surface != null) {
if (SDK_INT >= 23 && surface != null) {
setOutputSurfaceV23(codec, surface);
} else if (Util.SDK_INT >= 35) {
} else if (SDK_INT >= 35) {
detachOutputSurfaceV35(codec);
} else {
throw new IllegalStateException();
@ -2323,7 +2325,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
MediaFormatUtil.maybeSetInteger(
mediaFormat, MediaFormat.KEY_MAX_INPUT_SIZE, codecMaxValues.inputSize);
// Set codec configuration values.
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, 0 /* realtime priority */);
if (codecOperatingRate != CODEC_OPERATING_RATE_UNSET) {
mediaFormat.setFloat(MediaFormat.KEY_OPERATING_RATE, codecOperatingRate);
@ -2337,7 +2339,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
mediaFormat.setFeatureEnabled(CodecCapabilities.FEATURE_TunneledPlayback, true);
mediaFormat.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, tunnelingAudioSessionId);
}
if (Util.SDK_INT >= 35) {
if (SDK_INT >= 35) {
mediaFormat.setInteger(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
}
return mediaFormat;
@ -2557,7 +2559,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
}
private static boolean evaluateDeviceNeedsSetOutputSurfaceWorkaround() {
if (Util.SDK_INT <= 28) {
if (SDK_INT <= 28) {
// Workaround for MiTV and MiBox devices which have been observed broken up to API 28.
// https://github.com/google/ExoPlayer/issues/5169,
// https://github.com/google/ExoPlayer/issues/6899.
@ -2578,7 +2580,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
break; // Do nothing.
}
}
if (Util.SDK_INT <= 27 && "HWEML".equals(Build.DEVICE)) {
if (SDK_INT <= 27 && "HWEML".equals(Build.DEVICE)) {
// Workaround for Huawei P20:
// https://github.com/google/ExoPlayer/issues/4468#issuecomment-459291645.
return true;
@ -2598,7 +2600,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
default:
break; // Do nothing.
}
if (Util.SDK_INT <= 26) {
if (SDK_INT <= 26) {
// In general, devices running API level 27 or later should be unaffected unless observed
// otherwise. Enable the workaround on a per-device basis. Works around:
// https://github.com/google/ExoPlayer/issues/3236,
@ -2795,7 +2797,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
// This was fixed in https://android-review.googlesource.com/1156807.
//
// The workaround queues the event for subsequent processing, where the lock will not be held.
if (Util.SDK_INT < 30) {
if (SDK_INT < 30) {
Message message =
Message.obtain(
handler,

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.video;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.VideoFrameProcessor.DROP_OUTPUT_FRAME;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -114,6 +115,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
private VideoGraph.@MonotonicNonNull Factory videoGraphFactory;
private List<Effect> compositionEffects;
private VideoCompositorSettings compositorSettings;
private boolean enablePlaylistMode;
private Clock clock;
private boolean requestOpenGlToneMapping;
private boolean built;
@ -184,6 +186,36 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
return this;
}
/**
* Sets whether to enable playlist mode.
*
* <p>The default value is {@code false}.
*
* <p>This should only be set to {@code true} if there is a single {@linkplain
* PlaybackVideoGraphWrapper#getSink(int) input sink}.
*
* <p>If {@code true}, the {@link VideoGraph} output is considered as a playlist of clips. In
* this case, {@link PlaybackVideoGraphWrapper#startRendering()} and {@link
* PlaybackVideoGraphWrapper#stopRendering()} are called internally, when the corresponding
* methods are caller on the sink.
*
* <p>If {@code false}, the {@link VideoGraph} output is considered as a single clip. In this
* case, the caller is responsible for calling {@link
* PlaybackVideoGraphWrapper#startRendering()} and {@link
* PlaybackVideoGraphWrapper#stopRendering()}.
*
* @param enablePlaylistMode Whether to enable playlist mode.
* @return This builder, for convenience.
*/
@CanIgnoreReturnValue
public Builder setEnablePlaylistMode(boolean enablePlaylistMode) {
// This is set to true for ExoPlayer.setVideoEffects(). It's always false in
// CompositionPlayer, even if the Composition has a single sequence, because CompositionPlayer
// shouldn't behave differently for single and multi-sequence.
this.enablePlaylistMode = enablePlaylistMode;
return this;
}
/**
* Sets the {@link Clock} that will be used.
*
@ -270,6 +302,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
private final SparseArray<InputVideoSink> inputVideoSinks;
private final List<Effect> compositionEffects;
private final VideoCompositorSettings compositorSettings;
private final boolean enablePlaylistMode;
private final VideoSink defaultVideoSink;
private final VideoSink.VideoFrameHandler videoFrameHandler;
private final Clock clock;
@ -320,6 +353,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
inputVideoSinks = new SparseArray<>();
compositionEffects = builder.compositionEffects;
compositorSettings = builder.compositorSettings;
enablePlaylistMode = builder.enablePlaylistMode;
clock = builder.clock;
defaultVideoSink = new DefaultVideoSink(builder.videoFrameReleaseControl, clock);
videoFrameHandler =
@ -362,6 +396,16 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
listeners.remove(listener);
}
/** Starts rendering to the output surface. */
public void startRendering() {
defaultVideoSink.startRendering();
}
/** Stops rendering to the output surface. */
public void stopRendering() {
defaultVideoSink.stopRendering();
}
// VideoSinkProvider methods
@Override
@ -497,7 +541,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
if (requestOpenGlToneMapping) {
outputColorInfo = ColorInfo.SDR_BT709_LIMITED;
} else if (inputColorInfo.colorTransfer == C.COLOR_TRANSFER_HLG
&& Util.SDK_INT < 34
&& SDK_INT < 34
&& GlUtil.isBt2020PqExtensionSupported()) {
// PQ SurfaceView output is supported from API 33, but HLG output is supported from API
// 34. Therefore, convert HLG to PQ if PQ is supported, so that HLG input can be displayed
@ -506,8 +550,7 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
inputColorInfo.buildUpon().setColorTransfer(C.COLOR_TRANSFER_ST2084).build();
// Force OpenGL tone mapping if the GL extension required to output HDR colors is not
// available. OpenGL tone mapping is only supported on API 29+.
} else if (!GlUtil.isColorTransferSupported(inputColorInfo.colorTransfer)
&& Util.SDK_INT >= 29) {
} else if (!GlUtil.isColorTransferSupported(inputColorInfo.colorTransfer) && SDK_INT >= 29) {
Log.w(
TAG,
Util.formatInvariant(
@ -625,6 +668,10 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
checkStateNotNull(handler).post(() -> pendingFlushCount--);
}
private void joinPlayback(boolean renderNextFrameImmediately) {
defaultVideoSink.join(renderNextFrameImmediately);
}
private void setVideoFrameMetadataListener(
VideoFrameMetadataListener videoFrameMetadataListener) {
this.videoFrameMetadataListener = videoFrameMetadataListener;
@ -704,12 +751,16 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
@Override
public void startRendering() {
defaultVideoSink.startRendering();
if (enablePlaylistMode) {
PlaybackVideoGraphWrapper.this.startRendering();
}
}
@Override
public void stopRendering() {
defaultVideoSink.stopRendering();
if (enablePlaylistMode) {
PlaybackVideoGraphWrapper.this.stopRendering();
}
}
@Override
@ -976,7 +1027,9 @@ public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, Video
@Override
public void join(boolean renderNextFrameImmediately) {
defaultVideoSink.join(renderNextFrameImmediately);
if (enablePlaylistMode) {
PlaybackVideoGraphWrapper.this.joinPlayback(renderNextFrameImmediately);
}
}
@Override

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.video;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.content.Context;
@ -297,7 +298,7 @@ public final class VideoFrameReleaseHelper {
* called to update the surface.
*/
private void updateSurfaceMediaFrameRate() {
if (Util.SDK_INT < 30 || surface == null) {
if (SDK_INT < 30 || surface == null) {
return;
}
@ -345,7 +346,7 @@ public final class VideoFrameReleaseHelper {
* unchanged.
*/
private void updateSurfacePlaybackFrameRate(boolean forceUpdate) {
if (Util.SDK_INT < 30
if (SDK_INT < 30
|| surface == null
|| changeFrameRateStrategy == C.VIDEO_CHANGE_FRAME_RATE_STRATEGY_OFF) {
return;
@ -371,7 +372,7 @@ public final class VideoFrameReleaseHelper {
* C#VIDEO_CHANGE_FRAME_RATE_STRATEGY_OFF}.
*/
private void clearSurfaceFrameRate() {
if (Util.SDK_INT < 30
if (SDK_INT < 30
|| surface == null
|| changeFrameRateStrategy == C.VIDEO_CHANGE_FRAME_RATE_STRATEGY_OFF
|| surfacePlaybackFrameRate == 0) {

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.exoplayer.AudioFocusManager.PLAYER_COMMAND_DO_NOT_PLAY;
import static androidx.media3.exoplayer.AudioFocusManager.PLAYER_COMMAND_PLAY_WHEN_READY;
import static androidx.media3.exoplayer.AudioFocusManager.PLAYER_COMMAND_WAIT_FOR_CALLBACK;
@ -29,7 +30,6 @@ import android.os.Looper;
import androidx.media3.common.AudioAttributes;
import androidx.media3.common.C;
import androidx.media3.common.Player;
import androidx.media3.common.util.Util;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
@ -550,7 +550,7 @@ public class AudioFocusManagerTest {
}
private int getAudioFocusGainFromRequest(ShadowAudioManager.AudioFocusRequest audioFocusRequest) {
return Util.SDK_INT >= 26
return SDK_INT >= 26
? audioFocusRequest.audioFocusRequest.getFocusGain()
: audioFocusRequest.durationHint;
}

View File

@ -18,6 +18,7 @@ package androidx.media3.exoplayer.audio;
import static android.media.AudioFormat.CHANNEL_OUT_5POINT1;
import static android.media.AudioFormat.CHANNEL_OUT_STEREO;
import static android.media.AudioFormat.ENCODING_AC3;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.test.utils.robolectric.ShadowMediaCodecConfig.CODEC_INFO_AAC;
import static androidx.media3.test.utils.robolectric.ShadowMediaCodecConfig.CODEC_INFO_AC3;
@ -44,7 +45,6 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.Player;
import androidx.media3.common.Tracks;
import androidx.media3.common.Tracks.Group;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.DecoderCounters;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.Renderer;
@ -462,7 +462,7 @@ public class AudioCapabilitiesEndToEndTest {
.setFlags(0)
.build());
directPlaybackDevice = createDirectPlaybackDevice(ENCODING_AC3, CHANNEL_OUT_5POINT1);
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
shadowOf(audioManager).addOutputDeviceWithDirectProfiles(checkNotNull(directPlaybackDevice));
}
shadowOf(audioManager)
@ -474,7 +474,7 @@ public class AudioCapabilitiesEndToEndTest {
ShadowAudioTrack.clearAllowedNonPcmEncodings();
ShadowAudioTrack.clearDirectPlaybackSupportedFormats();
if (directPlaybackDevice != null) {
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
shadowOf(audioManager).removeOutputDeviceWithDirectProfiles(directPlaybackDevice);
}
shadowOf(audioManager)
@ -486,7 +486,7 @@ public class AudioCapabilitiesEndToEndTest {
private void setupDefaultPcmSupport() {
AudioDeviceInfoBuilder defaultDevice =
AudioDeviceInfoBuilder.newBuilder().setType(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
defaultDevice.setProfiles(ImmutableList.of(createPcmProfile()));
shadowOf(audioManager).addOutputDeviceWithDirectProfiles(defaultDevice.build());
} else {
@ -510,7 +510,7 @@ public class AudioCapabilitiesEndToEndTest {
private static AudioDeviceInfo createDirectPlaybackDevice(int encoding, int channelMask) {
AudioDeviceInfoBuilder directPlaybackDevice =
AudioDeviceInfoBuilder.newBuilder().setType(AudioDeviceInfo.TYPE_HDMI);
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
ImmutableList<AudioProfile> expectedProfiles =
ImmutableList.of(
AudioProfileBuilder.newBuilder()

View File

@ -16,6 +16,7 @@
package androidx.media3.exoplayer.audio;
import static android.media.AudioFormat.CHANNEL_OUT_5POINT1;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.exoplayer.audio.AudioCapabilities.ALL_SURROUND_ENCODINGS_AND_MAX_CHANNELS;
import static androidx.media3.exoplayer.audio.AudioCapabilities.getCapabilities;
@ -37,7 +38,6 @@ import androidx.media3.common.AudioAttributes;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Util;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
@ -489,7 +489,7 @@ public class AudioCapabilitiesTest {
audioAttributes.getAudioAttributesV21().audioAttributes);
AudioDeviceInfoBuilder deviceInfoBuilder =
AudioDeviceInfoBuilder.newBuilder().setType(AudioDeviceInfo.TYPE_HDMI);
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
ImmutableList<AudioProfile> expectedProfiles =
ImmutableList.of(
AudioProfileBuilder.newBuilder()

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.audio;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.exoplayer.audio.AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY;
import static androidx.media3.exoplayer.audio.AudioSink.SINK_FORMAT_SUPPORTED_WITH_TRANSCODING;
@ -774,7 +775,7 @@ public final class DefaultAudioSinkTest {
// Adding the permission to the test AndroidManifest.xml doesn't work to appease lint.
@SuppressWarnings({"StickyBroadcast", "MissingPermission"})
private void addHdmiDevice() {
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
// AudioFormat.getChannelIndexMask() in the implementation of
// ShadowAudioTrack.addDirectPlaybackSupport requires API 23+.
// https://cs.android.com/android/platform/superproject/main/+/main:external/robolectric/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioTrack.java?q=format.getChannelIndexMask()
@ -794,7 +795,7 @@ public final class DefaultAudioSinkTest {
// https://cs.android.com/android/platform/superproject/main/+/main:external/robolectric/shadows/framework/src/main/java/org/robolectric/shadows/AudioDeviceInfoBuilder.java?q=VERSION_CODES.M
AudioDeviceInfoBuilder hdmiDeviceBuilder =
AudioDeviceInfoBuilder.newBuilder().setType(AudioDeviceInfo.TYPE_HDMI);
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
ImmutableList<AudioProfile> expectedProfiles =
ImmutableList.of(
AudioProfileBuilder.newBuilder()
@ -833,7 +834,7 @@ public final class DefaultAudioSinkTest {
// Adding the permission to the test AndroidManifest.xml doesn't work to appease lint.
@SuppressWarnings({"StickyBroadcast", "MissingPermission"})
private void removeHdmiDevice() {
if (Util.SDK_INT >= 23 && hdmiDevice != null) {
if (SDK_INT >= 23 && hdmiDevice != null) {
ShadowAudioTrack.clearAllowedNonPcmEncodings();
ShadowAudioTrack.clearDirectPlaybackSupportedFormats();
getShadowAudioManager().removeOutputDeviceWithDirectProfiles(hdmiDevice);
@ -851,7 +852,7 @@ public final class DefaultAudioSinkTest {
}
private void addBluetoothDevice() {
if (Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
// For API 33+, AudioManager.getDirectProfilesForAttributes returns the AudioProfile for the
// routed device. To simulate the Bluetooth is connected and routed, we need to remove the
// profile of the HDMI device, which means that the HDMI device is no longer routed, but
@ -859,7 +860,7 @@ public final class DefaultAudioSinkTest {
removeHdmiDevice();
AudioDeviceInfoBuilder bluetoothDeviceBuilder =
AudioDeviceInfoBuilder.newBuilder().setType(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
if (Util.SDK_INT >= 33) {
if (SDK_INT >= 33) {
bluetoothDeviceBuilder.setProfiles(ImmutableList.of(createPcmProfile()));
}
bluetoothDevice = bluetoothDeviceBuilder.build();
@ -872,7 +873,7 @@ public final class DefaultAudioSinkTest {
}
private void removeBluetoothDevice() {
if (Util.SDK_INT >= 23 && bluetoothDevice != null) {
if (SDK_INT >= 23 && bluetoothDevice != null) {
// Add back the HDMI device back as the routed device to simulate that the bluetooth device
// has gone and is no longer routed.
addHdmiDevice();

View File

@ -17,6 +17,7 @@ package androidx.media3.exoplayer.upstream;
import static android.net.NetworkInfo.State.CONNECTED;
import static android.net.NetworkInfo.State.DISCONNECTED;
import static android.os.Build.VERSION.SDK_INT;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
@ -32,7 +33,6 @@ import android.telephony.TelephonyManager;
import androidx.media3.common.C;
import androidx.media3.common.util.BackgroundExecutor;
import androidx.media3.common.util.NetworkTypeObserver;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSpec;
import androidx.media3.test.utils.FakeClock;
@ -796,7 +796,7 @@ public final class DefaultBandwidthMeterTest {
private void setActiveNetworkInfo(NetworkInfo networkInfo, int networkTypeOverride) {
// Set network info in ConnectivityManager and TelephonyDisplayInfo in TelephonyManager.
Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
Object displayInfo =
ShadowTelephonyManager.createTelephonyDisplayInfo(
networkInfo.getType(), networkTypeOverride);

View File

@ -17,6 +17,7 @@ package androidx.media3.exoplayer.upstream.experimental;
import static android.net.NetworkInfo.State.CONNECTED;
import static android.net.NetworkInfo.State.DISCONNECTED;
import static android.os.Build.VERSION.SDK_INT;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
@ -32,7 +33,6 @@ import android.telephony.TelephonyManager;
import androidx.media3.common.C;
import androidx.media3.common.util.BackgroundExecutor;
import androidx.media3.common.util.NetworkTypeObserver;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSpec;
import androidx.media3.test.utils.FakeDataSource;
@ -805,7 +805,7 @@ public final class ExperimentalBandwidthMeterTest {
private void setActiveNetworkInfo(NetworkInfo networkInfo, int networkTypeOverride) {
// Set network info in ConnectivityManager and TelephonyDisplayInfo in TelephonyManager.
Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
Object displayInfo =
ShadowTelephonyManager.createTelephonyDisplayInfo(
networkInfo.getType(), networkTypeOverride);

View File

@ -19,6 +19,7 @@ import static android.media.MediaParser.PARAMETER_TS_IGNORE_AAC_STREAM;
import static android.media.MediaParser.PARAMETER_TS_IGNORE_AVC_STREAM;
import static android.media.MediaParser.PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM;
import static android.media.MediaParser.PARAMETER_TS_MODE;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_EAGERLY_EXPOSE_TRACK_TYPE;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_EXPOSE_CAPTION_FORMATS;
import static androidx.media3.exoplayer.source.mediaparser.MediaParserUtil.PARAMETER_IGNORE_TIMESTAMP_OFFSET;
@ -38,7 +39,6 @@ import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.source.mediaparser.InputReaderAdapterV30;
import androidx.media3.exoplayer.source.mediaparser.MediaParserUtil;
@ -270,7 +270,7 @@ public final class MediaParserHlsMediaChunkExtractor implements HlsMediaChunkExt
mediaParser.setParameter(PARAMETER_TS_IGNORE_AVC_STREAM, true);
}
}
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
MediaParserUtil.setLogSessionIdOnMediaParser(mediaParser, playerId);
}
return mediaParser;

View File

@ -83,6 +83,8 @@ import java.util.regex.Pattern;
// Lines are separated by an CRLF.
for (String line : RtspMessageUtil.splitRtspMessageBody(sdpString)) {
line = line.trim();
if ("".equals(line)) {
continue;
}

View File

@ -342,6 +342,25 @@ public class SessionDescriptionTest {
assertThat(sessionDescription.mediaDescriptionList.get(0).mediaTitle).isNull();
}
@Test
public void parse_sdpStringWithTrailingWhitespace_succeeds() throws Exception {
String testMediaSdpInfo =
"v=0\r\n"
+ "o=MNobody 2890844526 2890842807 IN IP4 192.0.2.46\r\n"
+ "s=SDP Seminar\r\n"
+ "i=Sun Apr 20 12:59:09 2025\n\r\n"
+ "t=0 0\r\n"
+ "a=control:*\r\n"
+ "m=audio 3456 RTP/AVP 0\r\n"
+ "i=\r\n"
+ "a=rtpmap:97 AC3/44100 \r\n";
SessionDescription sessionDescription = SessionDescriptionParser.parse(testMediaSdpInfo);
assertThat(sessionDescription.sessionInfo).isEqualTo("Sun Apr 20 12:59:09 2025");
assertThat(sessionDescription.mediaDescriptionList.get(0).mediaTitle).isNull();
}
@Test
public void parse_sdpStringWithEmptySessionAttribute_throwsParserException() {
String testMediaSdpInfo =

View File

@ -15,6 +15,8 @@
*/
package androidx.media3.exoplayer.workmanager;
import static android.os.Build.VERSION.SDK_INT;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.RequiresApi;
@ -49,7 +51,7 @@ public final class WorkManagerScheduler implements Scheduler {
private static final int SUPPORTED_REQUIREMENTS =
Requirements.NETWORK
| Requirements.NETWORK_UNMETERED
| (Util.SDK_INT >= 23 ? Requirements.DEVICE_IDLE : 0)
| (SDK_INT >= 23 ? Requirements.DEVICE_IDLE : 0)
| Requirements.DEVICE_CHARGING
| Requirements.DEVICE_STORAGE_NOT_LOW;
@ -105,7 +107,7 @@ public final class WorkManagerScheduler implements Scheduler {
} else {
builder.setRequiredNetworkType(NetworkType.NOT_REQUIRED);
}
if (Util.SDK_INT >= 23 && requirements.isIdleRequired()) {
if (SDK_INT >= 23 && requirements.isIdleRequired()) {
setRequiresDeviceIdle(builder);
}
if (requirements.isChargingRequired()) {

View File

@ -28,6 +28,7 @@ import androidx.media3.common.ParserException;
import androidx.media3.common.util.ParsableBitArray;
import androidx.media3.common.util.ParsableByteArray;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@ -240,6 +241,7 @@ public final class Ac4Util {
presentationConfig = dataBitArray.readBits(5); // presentation_config
isSingleSubstreamGroup = (presentationConfig == 0x1f);
}
ac4Presentation.version = presentationVersion;
boolean addEmdfSubstreams;
if (!(isSingleSubstream || isSingleSubstreamGroup) && presentationConfig == 6) {
@ -437,6 +439,9 @@ public final class Ac4Util {
"Can't determine channel count of presentation.");
}
String codecString =
createCodecsString(bitstreamVersion, ac4Presentation.version, ac4Presentation.level);
return new Format.Builder()
.setId(trackId)
.setSampleMimeType(MimeTypes.AUDIO_AC4)
@ -444,6 +449,7 @@ public final class Ac4Util {
.setSampleRate(sampleRate)
.setDrmInitData(drmInitData)
.setLanguage(language)
.setCodecs(codecString)
.build();
}
@ -631,6 +637,20 @@ public final class Ac4Util {
}
}
/**
* Create codec string based on bitstream version, presentation version and presentation level
*
* @param bitstreamVersion The bitstream version.
* @param presentationVersion The presentation version.
* @param mdcompat The mdcompat, i.e. presentation level.
* @return An AC-4 codec string built using the provided parameters.
*/
private static String createCodecsString(
int bitstreamVersion, int presentationVersion, int mdcompat) {
return Util.formatInvariant(
"ac-4.%02d.%02d.%02d", bitstreamVersion, presentationVersion, mdcompat);
}
/**
* Returns AC-4 format information given {@code data} containing a syncframe. The reading position
* of {@code data} will be modified.
@ -767,6 +787,7 @@ public final class Ac4Util {
public int numOfUmxObjects;
public boolean hasBackChannels;
public int topChannelPairs;
public int version;
public int level;
private Ac4Presentation() {
@ -775,6 +796,7 @@ public final class Ac4Util {
numOfUmxObjects = -1;
hasBackChannels = true;
topChannelPairs = 2;
version = 1;
level = 0;
}
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static android.view.KeyEvent.KEYCODE_MEDIA_FAST_FORWARD;
import static android.view.KeyEvent.KEYCODE_MEDIA_NEXT;
import static android.view.KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
@ -43,7 +44,6 @@ import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.graphics.drawable.IconCompat;
import androidx.media3.common.Player;
import androidx.media3.common.util.Util;
/** The default {@link MediaNotification.ActionFactory}. */
/* package */ final class DefaultActionFactory implements MediaNotification.ActionFactory {
@ -114,7 +114,7 @@ import androidx.media3.common.util.Util;
MediaSession mediaSession, @Player.Command long command) {
int keyCode = toKeyCode(command);
Intent intent = getMediaButtonIntent(mediaSession, keyCode);
if (Util.SDK_INT >= 26
if (SDK_INT >= 26
&& command == COMMAND_PLAY_PAUSE
&& !mediaSession.getPlayer().getPlayWhenReady()) {
return Api26.createForegroundServicePendingIntent(service, keyCode, intent);
@ -123,7 +123,7 @@ import androidx.media3.common.util.Util;
service,
/* requestCode= */ keyCode,
intent,
Util.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0);
SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0);
}
}
@ -136,7 +136,7 @@ import androidx.media3.common.util.Util;
service,
/* requestCode= */ KEYCODE_MEDIA_STOP,
intent,
Util.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0);
SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0);
}
private Intent getMediaButtonIntent(MediaSession mediaSession, int mediaKeyCode) {
@ -178,8 +178,7 @@ import androidx.media3.common.util.Util;
service,
/* requestCode= */ ++customActionPendingIntentRequestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
| (Util.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0));
PendingIntent.FLAG_UPDATE_CURRENT | (SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0));
}
/** Returns whether {@code intent} was part of a {@link #createMediaAction media action}. */

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.C.INDEX_UNSET;
import static androidx.media3.common.Player.COMMAND_INVALID;
import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE;
@ -371,7 +372,7 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
.setShowWhen(displayElapsedTimeWithChronometer)
.setUsesChronometer(displayElapsedTimeWithChronometer);
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
Api31.setForegroundServiceBehavior(builder);
}
@ -621,7 +622,7 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
}
private void ensureNotificationChannel() {
if (Util.SDK_INT < 26 || notificationManager.getNotificationChannel(channelId) != null) {
if (SDK_INT < 26 || notificationManager.getNotificationChannel(channelId) != null) {
return;
}
Api26.createNotificationChannel(
@ -682,7 +683,7 @@ public class DefaultMediaNotificationProvider implements MediaNotification.Provi
NotificationManager notificationManager, String channelId, String channelName) {
NotificationChannel channel =
new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);
if (Util.SDK_INT <= 27) {
if (SDK_INT <= 27) {
// API 28+ will automatically hide the app icon 'badge' for notifications using
// Notification.MediaStyle, but we have to manually hide it for APIs 26 (when badges were
// added) and 27.

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import android.app.ForegroundServiceStartNotAllowedException;
@ -25,14 +26,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.view.KeyEvent;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@ -125,7 +124,7 @@ public class MediaButtonReceiver extends BroadcastReceiver {
// Only handle the intent once with the earliest key event that arrives.
return;
}
if (Util.SDK_INT >= 26) {
if (SDK_INT >= 26) {
if (keyEvent.getKeyCode() != KeyEvent.KEYCODE_MEDIA_PLAY
&& keyEvent.getKeyCode() != KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
&& keyEvent.getKeyCode() != KeyEvent.KEYCODE_HEADSETHOOK) {
@ -159,8 +158,7 @@ public class MediaButtonReceiver extends BroadcastReceiver {
try {
ContextCompat.startForegroundService(context, intent);
} catch (/* ForegroundServiceStartNotAllowedException */ IllegalStateException e) {
if (Build.VERSION.SDK_INT >= 31
&& Api31.instanceOfForegroundServiceStartNotAllowedException(e)) {
if (SDK_INT >= 31 && Api31.instanceOfForegroundServiceStartNotAllowedException(e)) {
onForegroundServiceStartNotAllowedException(
intent, Api31.castToForegroundServiceStartNotAllowedException(e));
} else {

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkIndex;
import static androidx.media3.common.util.Assertions.checkNotNull;
@ -415,7 +416,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
return;
}
if (Util.SDK_INT >= 31 && platformController != null) {
if (SDK_INT >= 31 && platformController != null) {
// Ensure the platform session gets allow-listed to start a foreground service after receiving
// the play command.
platformController
@ -2533,7 +2534,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
private boolean requestConnectToService() {
int flags =
Util.SDK_INT >= 29
SDK_INT >= 29
? Context.BIND_AUTO_CREATE | Context.BIND_INCLUDE_CAPABILITIES
: Context.BIND_AUTO_CREATE;

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -1232,7 +1233,7 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
@Override
public void setDeviceMuted(boolean muted, @C.VolumeFlags int flags) {
if (Util.SDK_INT < 23) {
if (SDK_INT < 23) {
Log.w(TAG, "Session doesn't support setting mute state at API level less than 23");
return;
}
@ -1812,7 +1813,7 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
@Nullable
private static String getRoutingControllerId(MediaControllerCompat controllerCompat) {
if (Util.SDK_INT < 30) {
if (SDK_INT < 30) {
return null;
}
android.media.session.MediaController fwkController =

View File

@ -17,6 +17,7 @@ package androidx.media3.session;
import static android.app.Service.STOP_FOREGROUND_DETACH;
import static android.app.Service.STOP_FOREGROUND_REMOVE;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ -443,7 +444,7 @@ import java.util.concurrent.TimeoutException;
}
private void stopForeground(boolean removeNotifications) {
if (Util.SDK_INT >= 24) {
if (SDK_INT >= 24) {
Api24.stopForeground(mediaSessionService, removeNotifications);
} else {
mediaSessionService.stopForeground(removeNotifications);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.annotation.VisibleForTesting.PRIVATE;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
@ -798,7 +799,7 @@ public class MediaSession {
*/
@UnstableApi
public final void setSessionActivity(@Nullable PendingIntent activityPendingIntent) {
if (Util.SDK_INT >= 31 && activityPendingIntent != null) {
if (SDK_INT >= 31 && activityPendingIntent != null) {
checkArgument(Api31.isActivity(activityPendingIntent));
}
impl.setSessionActivity(activityPendingIntent);
@ -822,7 +823,7 @@ public class MediaSession {
@UnstableApi
public final void setSessionActivity(
ControllerInfo controller, @Nullable PendingIntent activityPendingIntent) {
if (Util.SDK_INT >= 31 && activityPendingIntent != null) {
if (SDK_INT >= 31 && activityPendingIntent != null) {
checkArgument(Api31.isActivity(activityPendingIntent));
}
impl.setSessionActivity(controller, activityPendingIntent);
@ -2257,7 +2258,7 @@ public class MediaSession {
@CanIgnoreReturnValue
@SuppressWarnings("unchecked")
public BuilderT setSessionActivity(PendingIntent pendingIntent) {
if (Util.SDK_INT >= 31) {
if (SDK_INT >= 31) {
checkArgument(Api31.isActivity(pendingIntent));
}
sessionActivity = checkNotNull(pendingIntent);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.Player.COMMAND_CHANGE_MEDIA_ITEMS;
import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE;
import static androidx.media3.common.Player.COMMAND_PREPARE;
@ -111,7 +112,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
private static final String TAG = "MediaSessionLegacyStub";
private static final int PENDING_INTENT_FLAG_MUTABLE =
Util.SDK_INT >= 31 ? PendingIntent.FLAG_MUTABLE : 0;
SDK_INT >= 31 ? PendingIntent.FLAG_MUTABLE : 0;
private static final String DEFAULT_MEDIA_SESSION_TAG_PREFIX = "androidx.media3.session.id";
private static final String DEFAULT_MEDIA_SESSION_TAG_DELIM = ".";
@ -151,7 +152,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
broadcastReceiverComponentName = queryPackageManagerForMediaButtonReceiver(context);
@Nullable ComponentName receiverComponentName = broadcastReceiverComponentName;
boolean isReceiverComponentAService = false;
if (receiverComponentName == null || Util.SDK_INT < 31) {
if (receiverComponentName == null || SDK_INT < 31) {
// Below API 26, media button events are sent to the receiver at runtime also. We always want
// these to arrive at the service at runtime. release() then set the receiver for restart if
// available.
@ -185,7 +186,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
intent.setComponent(receiverComponentName);
mediaButtonIntent =
isReceiverComponentAService
? (Util.SDK_INT >= 26
? (SDK_INT >= 26
? PendingIntent.getForegroundService(
context, /* requestCode= */ 0, intent, PENDING_INTENT_FLAG_MUTABLE)
: PendingIntent.getService(
@ -203,10 +204,10 @@ import org.checkerframework.checker.initialization.qual.Initialized;
new MediaSessionCompat(
context,
sessionCompatId,
Util.SDK_INT < 31 ? receiverComponentName : null,
Util.SDK_INT < 31 ? mediaButtonIntent : null,
SDK_INT < 31 ? receiverComponentName : null,
SDK_INT < 31 ? mediaButtonIntent : null,
/* sessionInfo= */ tokenExtras);
if (Util.SDK_INT >= 31 && broadcastReceiverComponentName != null) {
if (SDK_INT >= 31 && broadcastReceiverComponentName != null) {
Api31.setMediaButtonBroadcastReceiver(sessionCompat, broadcastReceiverComponentName);
}
@ -249,7 +250,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
@SuppressWarnings("PendingIntentMutability") // We can't use SaferPendingIntent.
public void release() {
if (Util.SDK_INT < 31) {
if (SDK_INT < 31) {
if (broadcastReceiverComponentName == null) {
// No broadcast receiver available. Playback resumption not supported.
setMediaButtonReceiver(sessionCompat, /* mediaButtonReceiverIntent= */ null);

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkStateNotNull;
@ -657,7 +658,7 @@ public abstract class MediaSessionService extends Service {
getMediaNotificationManager().shouldRunInForeground(startInForegroundWhenPaused);
onUpdateNotification(session, startInForegroundRequired);
} catch (/* ForegroundServiceStartNotAllowedException */ IllegalStateException e) {
if ((Util.SDK_INT >= 31) && Api31.instanceOfForegroundServiceStartNotAllowedException(e)) {
if ((SDK_INT >= 31) && Api31.instanceOfForegroundServiceStartNotAllowedException(e)) {
Log.e(TAG, "Failed to start foreground", e);
onForegroundServiceStartNotAllowedException();
return false;
@ -733,7 +734,7 @@ public abstract class MediaSessionService extends Service {
@Override
public boolean onPlayRequested(MediaSession session) {
if (Util.SDK_INT < 31 || Util.SDK_INT >= 33) {
if (SDK_INT < 31 || SDK_INT >= 33) {
return true;
}
// Check if service can start foreground successfully on Android 12 and 12L.

View File

@ -16,6 +16,7 @@
package androidx.media3.session;
import static android.Manifest.permission.MEDIA_CONTENT_CONTROL;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.core.app.NotificationCompat.COLOR_DEFAULT;
import static androidx.media3.common.util.Assertions.checkArgument;
@ -33,7 +34,6 @@ import androidx.core.app.NotificationBuilderWithBuilderAccessor;
import androidx.core.graphics.drawable.IconCompat;
import androidx.media3.common.util.NullableType;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -200,7 +200,7 @@ public class MediaStyleNotificationHelper {
if (actionsToShowInCompact != null) {
style.setShowActionsInCompactView(actionsToShowInCompact);
}
if (Util.SDK_INT >= 34 && remoteDeviceName != null) {
if (SDK_INT >= 34 && remoteDeviceName != null) {
Api34Impl.setRemotePlaybackInfo(
style, remoteDeviceName, remoteDeviceIconRes, remoteDeviceIntent);
builder.getBuilder().setStyle(style);
@ -332,7 +332,7 @@ public class MediaStyleNotificationHelper {
@Override
public void apply(NotificationBuilderWithBuilderAccessor builder) {
if (Util.SDK_INT < 24) {
if (SDK_INT < 24) {
super.apply(builder);
return;
}
@ -341,7 +341,7 @@ public class MediaStyleNotificationHelper {
if (actionsToShowInCompact != null) {
style.setShowActionsInCompactView(actionsToShowInCompact);
}
if (Util.SDK_INT >= 34 && remoteDeviceName != null) {
if (SDK_INT >= 34 && remoteDeviceName != null) {
Api34Impl.setRemotePlaybackInfo(
style, remoteDeviceName, remoteDeviceIconRes, remoteDeviceIntent);
builder.getBuilder().setStyle(style);
@ -357,7 +357,7 @@ public class MediaStyleNotificationHelper {
@Nullable
@SuppressWarnings("nullness:override.return") // NotificationCompat doesn't annotate @Nullable
public RemoteViews makeContentView(NotificationBuilderWithBuilderAccessor builder) {
if (Util.SDK_INT >= 24) {
if (SDK_INT >= 24) {
// No custom content view required
return null;
}
@ -385,7 +385,7 @@ public class MediaStyleNotificationHelper {
@Nullable
@SuppressWarnings("nullness:override.return") // NotificationCompat doesn't annotate @Nullable
public RemoteViews makeBigContentView(NotificationBuilderWithBuilderAccessor builder) {
if (Util.SDK_INT >= 24) {
if (SDK_INT >= 24) {
// No custom big content view required
return null;
}
@ -414,7 +414,7 @@ public class MediaStyleNotificationHelper {
@Nullable
@SuppressWarnings("nullness:override.return") // NotificationCompat doesn't annotate @Nullable
public RemoteViews makeHeadsUpContentView(NotificationBuilderWithBuilderAccessor builder) {
if (Util.SDK_INT >= 24) {
if (SDK_INT >= 24) {
// No custom heads up content view required
return null;
}

View File

@ -15,13 +15,13 @@
*/
package androidx.media3.session.legacy;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.RestrictTo;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.nullness.qual.PolyNull;
@ -88,7 +88,7 @@ public final class LegacyParcelableUtil {
// TODO: b/335804969 - Remove this workaround once the bug fix is in the androidx.media dependency
@SuppressWarnings("unchecked")
private static <T> T maybeApplyMediaDescriptionParcelableBugWorkaround(T value) {
if (Util.SDK_INT < 21 || Util.SDK_INT >= 23) {
if (SDK_INT >= 23) {
return value;
}
if (value instanceof android.support.v4.media.MediaBrowserCompat.MediaItem) {

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.session;
import static android.os.Build.VERSION.SDK_INT;
import static com.google.common.truth.Truth.assertThat;
import android.app.PendingIntent;
@ -23,7 +24,6 @@ import android.content.Intent;
import android.os.Bundle;
import androidx.media3.common.MediaLibraryInfo;
import androidx.media3.common.Player;
import androidx.media3.common.util.Util;
import androidx.media3.test.utils.TestExoPlayerBuilder;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@ -53,7 +53,7 @@ public class ConnectionStateTest {
context,
/* requestCode= */ 0,
new Intent(),
/* flags= */ Util.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0),
/* flags= */ SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0),
/* customLayout= */ ImmutableList.of(
new CommandButton.Builder(CommandButton.ICON_ARTIST)
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

View File

@ -15,6 +15,7 @@ track 0:
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4
codecs = ac-4.02.02.00
maxInputSize = 622
channelCount = 2
sampleRate = 48000

Some files were not shown because too many files have changed in this diff Show More