Does nothing for API levels < 19 or when the {@link CaptioningManager} is disabled. + *
Does nothing when the {@link CaptioningManager} is disabled.
*
* @param context A {@link Context}.
* @return This builder.
@@ -631,8 +630,20 @@ public class TrackSelectionParameters implements Bundleable {
@CanIgnoreReturnValue
public Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(
Context context) {
- if (Util.SDK_INT >= 19) {
- setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(context);
+ if (Util.SDK_INT < 23 && Looper.myLooper() == null) {
+ // Android platform bug (pre-Marshmallow) that causes RuntimeExceptions when
+ // CaptioningService is instantiated from a non-Looper thread. See [internal: b/143779904].
+ return this;
+ }
+ CaptioningManager captioningManager =
+ (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+ if (captioningManager == null || !captioningManager.isEnabled()) {
+ return this;
+ }
+ preferredTextRoleFlags = C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND;
+ Locale preferredLocale = captioningManager.getLocale();
+ if (preferredLocale != null) {
+ preferredTextLanguages = ImmutableList.of(Util.getLocaleLanguageTag(preferredLocale));
}
return this;
}
@@ -832,26 +843,6 @@ public class TrackSelectionParameters implements Bundleable {
return new TrackSelectionParameters(this);
}
- @RequiresApi(19)
- private void setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(
- Context context) {
- if (Util.SDK_INT < 23 && Looper.myLooper() == null) {
- // Android platform bug (pre-Marshmallow) that causes RuntimeExceptions when
- // CaptioningService is instantiated from a non-Looper thread. See [internal: b/143779904].
- return;
- }
- CaptioningManager captioningManager =
- (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
- if (captioningManager == null || !captioningManager.isEnabled()) {
- return;
- }
- preferredTextRoleFlags = C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND;
- Locale preferredLocale = captioningManager.getLocale();
- if (preferredLocale != null) {
- preferredTextLanguages = ImmutableList.of(Util.getLocaleLanguageTag(preferredLocale));
- }
- }
-
private static ImmutableList Returns {@code 0} if no {@link EGLContext} {@linkplain #createFocusedPlaceholderEglSurface
* is focused}.
*/
- @RequiresApi(17)
public static long getContextMajorVersion() throws GlException {
- return Api17.getContextMajorVersion();
+ int[] currentEglContextVersion = new int[1];
+ EGL14.eglQueryContext(
+ EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
+ EGL14.eglGetCurrentContext(),
+ EGL_CONTEXT_CLIENT_VERSION,
+ currentEglContextVersion,
+ /* offset= */ 0);
+ checkGlError();
+ return currentEglContextVersion[0];
}
/**
@@ -384,10 +422,20 @@ public final class GlUtil {
* #createFocusedPlaceholderEglSurface is focused}, or the focused {@link EGLContext} version is
* less than 3.0.
*/
- @RequiresApi(17)
public static long createGlSyncFence() throws GlException {
- // If the context is an OpenGL 3.0 context, we must be running API 18 or later.
- return Api17.getContextMajorVersion() >= 3 ? Api18.createSyncFence() : 0;
+ if (getContextMajorVersion() >= 3) {
+ long syncObject = GLES30.glFenceSync(GLES30.GL_SYNC_GPU_COMMANDS_COMPLETE, /* flags= */ 0);
+ checkGlError();
+ // Due to specifics of OpenGL, it might happen that the fence creation command is not yet
+ // sent into the GPU command queue, which can cause other threads to wait infinitely if
+ // the glSyncWait/glClientSyncWait command went into the GPU earlier. Hence, we have to
+ // call glFlush to ensure that glFenceSync is inside of the GPU command queue.
+ GLES20.glFlush();
+ checkGlError();
+ return syncObject;
+ } else {
+ return 0;
+ }
}
/**
@@ -396,22 +444,13 @@ public final class GlUtil {
* The {@code syncObject} must not be used after deletion.
*/
public static void deleteSyncObject(long syncObject) throws GlException {
- // If the sync object is set, we must be running API 18 or later.
- if (Util.SDK_INT >= 18) {
- Api18.deleteSyncObject(syncObject);
- }
+ deleteSyncObjectQuietly(syncObject);
+ checkGlError();
}
/** Releases the GL sync object if set, suppressing any error. */
public static void deleteSyncObjectQuietly(long syncObject) {
- if (Util.SDK_INT >= 18) {
- try {
- // glDeleteSync ignores a 0-valued sync object.
- Api18.deleteSyncObject(syncObject);
- } catch (GlException unused) {
- // Suppress exceptions.
- }
- }
+ GLES30.glDeleteSync(syncObject);
}
/**
@@ -424,15 +463,14 @@ public final class GlUtil {
// Fallback to using glFinish for synchronization when fence creation failed.
GLES20.glFinish();
} else {
- // If the sync object is set, we must be running API 18 or later.
- Api18.waitSync(syncObject);
+ GLES30.glWaitSync(syncObject, /* flags= */ 0, GLES30.GL_TIMEOUT_IGNORED);
+ checkGlError();
}
}
/** Gets the current {@link EGLContext context}. */
- @RequiresApi(17)
public static EGLContext getCurrentContext() {
- return Api17.getCurrentContext();
+ return EGL14.eglGetCurrentContext();
}
/**
@@ -506,19 +544,16 @@ public final class GlUtil {
* Makes the specified {@code eglSurface} the render target, using a viewport of {@code width} by
* {@code height} pixels.
*/
- @RequiresApi(17)
public static void focusEglSurface(
EGLDisplay eglDisplay, EGLContext eglContext, EGLSurface eglSurface, int width, int height)
throws GlException {
- Api17.focusRenderTarget(
- eglDisplay, eglContext, eglSurface, /* framebuffer= */ 0, width, height);
+ focusRenderTarget(eglDisplay, eglContext, eglSurface, /* framebuffer= */ 0, width, height);
}
/**
* Makes the specified {@code framebuffer} the render target, using a viewport of {@code width} by
* {@code height} pixels.
*/
- @RequiresApi(17)
public static void focusFramebuffer(
EGLDisplay eglDisplay,
EGLContext eglContext,
@@ -527,7 +562,7 @@ public final class GlUtil {
int width,
int height)
throws GlException {
- Api17.focusRenderTarget(eglDisplay, eglContext, eglSurface, framebuffer, width, height);
+ focusRenderTarget(eglDisplay, eglContext, eglSurface, framebuffer, width, height);
}
/**
@@ -614,7 +649,6 @@ public final class GlUtil {
// TODO(b/227624622): Implement a pixel test that confirms 16f has less posterization.
// TODO - b/309459038: Consider renaming the method, as the created textures are uninitialized.
if (useHighPrecisionColorComponents) {
- checkState(Util.SDK_INT >= 18, "GLES30 extensions are not supported below API 18.");
return createTextureUninitialized(width, height, GLES30.GL_RGBA16F, GLES30.GL_HALF_FLOAT);
}
return createTextureUninitialized(width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE);
@@ -721,20 +755,39 @@ public final class GlUtil {
* This is a no-op if called on already-destroyed {@link EGLDisplay} and {@link EGLContext}
* instances.
*/
- @RequiresApi(17)
public static void destroyEglContext(
@Nullable EGLDisplay eglDisplay, @Nullable EGLContext eglContext) throws GlException {
- Api17.destroyEglContext(eglDisplay, eglContext);
+ if (eglDisplay == null) {
+ return;
+ }
+ EGL14.eglMakeCurrent(
+ eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
+ checkEglException("Error releasing context");
+ if (eglContext != null) {
+ EGL14.eglDestroyContext(eglDisplay, eglContext);
+ checkEglException("Error destroying context");
+ }
+ EGL14.eglReleaseThread();
+ checkEglException("Error releasing thread");
+ EGL14.eglTerminate(eglDisplay);
+ checkEglException("Error terminating display");
}
/**
* Destroys the {@link EGLSurface} identified by the provided {@link EGLDisplay} and {@link
* EGLSurface}.
*/
- @RequiresApi(17)
public static void destroyEglSurface(
@Nullable EGLDisplay eglDisplay, @Nullable EGLSurface eglSurface) throws GlException {
- Api17.destroyEglSurface(eglDisplay, eglSurface);
+ if (eglDisplay == null || eglSurface == null) {
+ return;
+ }
+ if (EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW) == EGL_NO_SURFACE) {
+ return;
+ }
+
+ EGL14.eglDestroySurface(eglDisplay, eglSurface);
+ checkEglException("Error destroying surface");
}
/** Deletes a framebuffer, or silently ignores the method call if {@code fboId} is unused. */
@@ -760,203 +813,46 @@ public final class GlUtil {
}
}
- @RequiresApi(17)
- private static final class Api17 {
- private Api17() {}
-
- @DoNotInline
- public static EGLDisplay getDefaultEglDisplay() throws GlException {
- EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
- checkGlException(!eglDisplay.equals(EGL14.EGL_NO_DISPLAY), "No EGL display.");
- checkGlException(
- EGL14.eglInitialize(
- eglDisplay,
- /* unusedMajor */ new int[1],
- /* majorOffset= */ 0,
- /* unusedMinor */ new int[1],
- /* minorOffset= */ 0),
- "Error in eglInitialize.");
- checkGlError();
- return eglDisplay;
- }
-
- @DoNotInline
- public static EGLContext createEglContext(
- EGLContext sharedContext, EGLDisplay eglDisplay, int version, int[] configAttributes)
- throws GlException {
- int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, version, EGL14.EGL_NONE};
- EGLContext eglContext =
- EGL14.eglCreateContext(
- eglDisplay,
- getEglConfig(eglDisplay, configAttributes),
- sharedContext,
- contextAttributes,
- /* offset= */ 0);
- if (eglContext == null) {
- EGL14.eglTerminate(eglDisplay);
- throw new GlException(
- "eglCreateContext() failed to create a valid context. The device may not support EGL"
- + " version "
- + version);
- }
- checkGlError();
- return eglContext;
- }
-
- @DoNotInline
- public static EGLContext getCurrentContext() {
- return EGL14.eglGetCurrentContext();
- }
-
- @DoNotInline
- private static EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] attributes)
- throws GlException {
- EGLConfig[] eglConfigs = new EGLConfig[1];
- if (!EGL14.eglChooseConfig(
- eglDisplay,
- attributes,
- /* attrib_listOffset= */ 0,
- eglConfigs,
- /* configsOffset= */ 0,
- /* config_size= */ 1,
- /* unusedNumConfig */ new int[1],
- /* num_configOffset= */ 0)) {
- throw new GlException("eglChooseConfig failed.");
- }
- return eglConfigs[0];
- }
-
- @DoNotInline
- public static boolean isExtensionSupported(String extensionName) {
- EGLDisplay display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
- @Nullable String eglExtensions = EGL14.eglQueryString(display, EGL10.EGL_EXTENSIONS);
- return eglExtensions != null && eglExtensions.contains(extensionName);
- }
-
- @DoNotInline
- public static int getContextMajorVersion() throws GlException {
- int[] currentEglContextVersion = new int[1];
- EGL14.eglQueryContext(
- EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
- EGL14.eglGetCurrentContext(),
- EGL_CONTEXT_CLIENT_VERSION,
- currentEglContextVersion,
- /* offset= */ 0);
- checkGlError();
- return currentEglContextVersion[0];
- }
-
- @DoNotInline
- public static EGLSurface createEglSurface(
- EGLDisplay eglDisplay, Object surface, int[] configAttributes, int[] windowAttributes)
- throws GlException {
- EGLSurface eglSurface =
- EGL14.eglCreateWindowSurface(
- eglDisplay,
- getEglConfig(eglDisplay, configAttributes),
- surface,
- windowAttributes,
- /* offset= */ 0);
- checkEglException("Error creating a new EGL surface");
- return eglSurface;
- }
-
- @DoNotInline
- public static EGLSurface createEglPbufferSurface(
- EGLDisplay eglDisplay, int[] configAttributes, int[] pbufferAttributes) throws GlException {
- EGLSurface eglSurface =
- EGL14.eglCreatePbufferSurface(
- eglDisplay,
- getEglConfig(eglDisplay, configAttributes),
- pbufferAttributes,
- /* offset= */ 0);
- checkEglException("Error creating a new EGL Pbuffer surface");
- return eglSurface;
- }
-
- @DoNotInline
- public static void focusRenderTarget(
- EGLDisplay eglDisplay,
- EGLContext eglContext,
- EGLSurface eglSurface,
- int framebuffer,
- int width,
- int height)
- throws GlException {
- EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
- checkEglException("Error making context current");
- focusFramebufferUsingCurrentContext(framebuffer, width, height);
- }
-
- @DoNotInline
- public static void destroyEglContext(
- @Nullable EGLDisplay eglDisplay, @Nullable EGLContext eglContext) throws GlException {
- if (eglDisplay == null) {
- return;
- }
- EGL14.eglMakeCurrent(
- eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
- checkEglException("Error releasing context");
- if (eglContext != null) {
- EGL14.eglDestroyContext(eglDisplay, eglContext);
- checkEglException("Error destroying context");
- }
- EGL14.eglReleaseThread();
- checkEglException("Error releasing thread");
- EGL14.eglTerminate(eglDisplay);
- checkEglException("Error terminating display");
- }
-
- @DoNotInline
- public static void destroyEglSurface(
- @Nullable EGLDisplay eglDisplay, @Nullable EGLSurface eglSurface) throws GlException {
- if (eglDisplay == null || eglSurface == null) {
- return;
- }
- if (EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW) == EGL_NO_SURFACE) {
- return;
- }
-
- EGL14.eglDestroySurface(eglDisplay, eglSurface);
- checkEglException("Error destroying surface");
- }
-
- @DoNotInline
- public static void checkEglException(String errorMessage) throws GlException {
- int error = EGL14.eglGetError();
- if (error != EGL14.EGL_SUCCESS) {
- throw new GlException(errorMessage + ", error code: 0x" + Integer.toHexString(error));
- }
+ private static EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] attributes)
+ throws GlException {
+ EGLConfig[] eglConfigs = new EGLConfig[1];
+ if (!EGL14.eglChooseConfig(
+ eglDisplay,
+ attributes,
+ /* attrib_listOffset= */ 0,
+ eglConfigs,
+ /* configsOffset= */ 0,
+ /* config_size= */ 1,
+ /* unusedNumConfig */ new int[1],
+ /* num_configOffset= */ 0)) {
+ throw new GlException("eglChooseConfig failed.");
}
+ return eglConfigs[0];
}
- @RequiresApi(18)
- private static final class Api18 {
- private Api18() {}
+ private static boolean isExtensionSupported(String extensionName) {
+ EGLDisplay display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+ @Nullable String eglExtensions = EGL14.eglQueryString(display, EGL10.EGL_EXTENSIONS);
+ return eglExtensions != null && eglExtensions.contains(extensionName);
+ }
- @DoNotInline
- public static long createSyncFence() throws GlException {
- long syncObject = GLES30.glFenceSync(GLES30.GL_SYNC_GPU_COMMANDS_COMPLETE, /* flags= */ 0);
- checkGlError();
- // Due to specifics of OpenGL, it might happen that the fence creation command is not yet
- // sent into the GPU command queue, which can cause other threads to wait infinitely if
- // the glSyncWait/glClientSyncWait command went into the GPU earlier. Hence, we have to
- // call glFlush to ensure that glFenceSync is inside of the GPU command queue.
- GLES20.glFlush();
- checkGlError();
- return syncObject;
- }
+ private static void focusRenderTarget(
+ EGLDisplay eglDisplay,
+ EGLContext eglContext,
+ EGLSurface eglSurface,
+ int framebuffer,
+ int width,
+ int height)
+ throws GlException {
+ EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
+ checkEglException("Error making context current");
+ focusFramebufferUsingCurrentContext(framebuffer, width, height);
+ }
- @DoNotInline
- public static void deleteSyncObject(long syncObject) throws GlException {
- GLES30.glDeleteSync(syncObject);
- checkGlError();
- }
-
- @DoNotInline
- public static void waitSync(long syncObject) throws GlException {
- GLES30.glWaitSync(syncObject, /* flags= */ 0, GLES30.GL_TIMEOUT_IGNORED);
- checkGlError();
+ private static void checkEglException(String errorMessage) throws GlException {
+ int error = EGL14.eglGetError();
+ if (error != EGL14.EGL_SUCCESS) {
+ throw new GlException(errorMessage + ", error code: 0x" + Integer.toHexString(error));
}
}
}
diff --git a/libraries/common/src/main/java/androidx/media3/common/util/TraceUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/TraceUtil.java
index 2d03a5357f..634aae42c2 100644
--- a/libraries/common/src/main/java/androidx/media3/common/util/TraceUtil.java
+++ b/libraries/common/src/main/java/androidx/media3/common/util/TraceUtil.java
@@ -15,10 +15,12 @@
*/
package androidx.media3.common.util;
-import androidx.annotation.RequiresApi;
+import android.os.Trace;
import androidx.media3.common.MediaLibraryInfo;
-/** Calls through to {@link android.os.Trace} methods on supported API levels. */
+/**
+ * Calls through to {@link Trace} methods if {@link MediaLibraryInfo#TRACE_ENABLED} is {@code true}.
+ */
@UnstableApi
public final class TraceUtil {
@@ -27,34 +29,24 @@ public final class TraceUtil {
/**
* Writes a trace message to indicate that a given section of code has begun.
*
- * @see android.os.Trace#beginSection(String)
+ * @see Trace#beginSection(String)
* @param sectionName The name of the code section to appear in the trace. This may be at most 127
* Unicode code units long.
*/
public static void beginSection(String sectionName) {
- if (MediaLibraryInfo.TRACE_ENABLED && Util.SDK_INT >= 18) {
- beginSectionV18(sectionName);
+ if (MediaLibraryInfo.TRACE_ENABLED) {
+ Trace.beginSection(sectionName);
}
}
/**
* Writes a trace message to indicate that a given section of code has ended.
*
- * @see android.os.Trace#endSection()
+ * @see Trace#endSection()
*/
public static void endSection() {
- if (MediaLibraryInfo.TRACE_ENABLED && Util.SDK_INT >= 18) {
- endSectionV18();
+ if (MediaLibraryInfo.TRACE_ENABLED) {
+ Trace.endSection();
}
}
-
- @RequiresApi(18)
- private static void beginSectionV18(String sectionName) {
- android.os.Trace.beginSection(sectionName);
- }
-
- @RequiresApi(18)
- private static void endSectionV18() {
- android.os.Trace.endSection();
- }
}
diff --git a/libraries/common/src/main/java/androidx/media3/common/util/Util.java b/libraries/common/src/main/java/androidx/media3/common/util/Util.java
index e79c4392a1..47b9508250 100644
--- a/libraries/common/src/main/java/androidx/media3/common/util/Util.java
+++ b/libraries/common/src/main/java/androidx/media3/common/util/Util.java
@@ -1560,7 +1560,6 @@ public final class Util {
* @throws NoSuchElementException If the array is empty.
*/
@UnstableApi
- @RequiresApi(18)
public static long minValue(SparseLongArray sparseLongArray) {
if (sparseLongArray.size() == 0) {
throw new NoSuchElementException();
@@ -1580,7 +1579,6 @@ public final class Util {
* @throws NoSuchElementException If the array is empty.
*/
@UnstableApi
- @RequiresApi(18)
public static long maxValue(SparseLongArray sparseLongArray) {
if (sparseLongArray.size() == 0) {
throw new NoSuchElementException();
@@ -3134,15 +3132,12 @@ public final class Util {
@UnstableApi
public static Point getCurrentDisplayModeSize(Context context) {
@Nullable Display defaultDisplay = null;
- if (SDK_INT >= 17) {
- @Nullable
- DisplayManager displayManager =
- (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
- // We don't expect displayManager to ever be null, so this check is just precautionary.
- // Consider removing it when the library minSdkVersion is increased to 17 or higher.
- if (displayManager != null) {
- defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
- }
+ @Nullable
+ DisplayManager displayManager =
+ (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+ // We don't expect displayManager to ever be null, so this check is just precautionary.
+ if (displayManager != null) {
+ defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
}
if (defaultDisplay == null) {
WindowManager windowManager =
@@ -3214,10 +3209,8 @@ public final class Util {
Point displaySize = new Point();
if (SDK_INT >= 23) {
getDisplaySizeV23(display, displaySize);
- } else if (SDK_INT >= 17) {
- getDisplaySizeV17(display, displaySize);
} else {
- getDisplaySizeV16(display, displaySize);
+ display.getRealSize(displaySize);
}
return displaySize;
}
@@ -3703,15 +3696,6 @@ public final class Util {
outSize.y = mode.getPhysicalHeight();
}
- @RequiresApi(17)
- private static void getDisplaySizeV17(Display display, Point outSize) {
- display.getRealSize(outSize);
- }
-
- private static void getDisplaySizeV16(Display display, Point outSize) {
- display.getSize(outSize);
- }
-
private static String[] getSystemLocales() {
Configuration config = Resources.getSystem().getConfiguration();
return SDK_INT >= 24
diff --git a/libraries/common/src/test/java/androidx/media3/common/util/BundleUtilTest.java b/libraries/common/src/test/java/androidx/media3/common/util/BundleUtilTest.java
deleted file mode 100644
index 749e66a3a7..0000000000
--- a/libraries/common/src/test/java/androidx/media3/common/util/BundleUtilTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package androidx.media3.common.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** Unit tests for {@link BundleUtil}. */
-@RunWith(AndroidJUnit4.class)
-public class BundleUtilTest {
-
- @Test
- public void getPutBinder() {
- String key = "key";
- IBinder binder = new Binder();
- Bundle bundle = new Bundle();
-
- BundleUtil.putBinder(bundle, key, binder);
- IBinder returnedBinder = BundleUtil.getBinder(bundle, key);
-
- assertThat(returnedBinder).isSameInstanceAs(binder);
- }
-}
diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java
index 4087767671..6a9a1d8af5 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/DefaultHttpDataSource.java
@@ -822,7 +822,7 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
*/
private static void maybeTerminateInputStream(
@Nullable HttpURLConnection connection, long bytesRemaining) {
- if (connection == null || Util.SDK_INT < 19 || Util.SDK_INT > 20) {
+ if (connection == null || Util.SDK_INT > 20) {
return;
}
diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/cache/CachedContentIndex.java b/libraries/datasource/src/main/java/androidx/media3/datasource/cache/CachedContentIndex.java
index bfb2a02e5e..f6894237e8 100644
--- a/libraries/datasource/src/main/java/androidx/media3/datasource/cache/CachedContentIndex.java
+++ b/libraries/datasource/src/main/java/androidx/media3/datasource/cache/CachedContentIndex.java
@@ -20,7 +20,6 @@ import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Util.castNonNull;
import static java.lang.Math.min;
-import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
@@ -347,19 +346,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
return cachedContent;
}
- @SuppressLint("GetInstance") // Suppress warning about specifying "BC" as an explicit provider.
- private static Cipher getCipher() throws NoSuchPaddingException, NoSuchAlgorithmException {
- // Workaround for https://issuetracker.google.com/issues/36976726
- if (Util.SDK_INT == 18) {
- try {
- return Cipher.getInstance("AES/CBC/PKCS5PADDING", "BC");
- } catch (Throwable ignored) {
- // ignored
- }
- }
- return Cipher.getInstance("AES/CBC/PKCS5PADDING");
- }
-
/**
* Returns an id which isn't used in the given array. If the maximum id in the array is smaller
* than {@link java.lang.Integer#MAX_VALUE} it just returns the next bigger integer. Otherwise it
@@ -526,7 +512,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (secretKey != null) {
Assertions.checkArgument(secretKey.length == 16);
try {
- cipher = getCipher();
+ cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
secretKeySpec = new SecretKeySpec(secretKey, "AES");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalStateException(e); // Should never happen.
diff --git a/libraries/effect/src/androidTest/java/androidx/media3/effect/EffectPlaybackTest.java b/libraries/effect/src/androidTest/java/androidx/media3/effect/EffectPlaybackTest.java
index 29de571455..8e6a2bbe07 100644
--- a/libraries/effect/src/androidTest/java/androidx/media3/effect/EffectPlaybackTest.java
+++ b/libraries/effect/src/androidTest/java/androidx/media3/effect/EffectPlaybackTest.java
@@ -24,7 +24,6 @@ import static androidx.media3.test.utils.BitmapPixelTestUtil.createArgb8888Bitma
import static androidx.media3.test.utils.BitmapPixelTestUtil.getBitmapAveragePixelAbsoluteDifferenceArgb8888;
import static androidx.media3.test.utils.BitmapPixelTestUtil.readBitmap;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeTrue;
import android.app.Instrumentation;
import android.graphics.Bitmap;
@@ -103,8 +102,6 @@ public class EffectPlaybackTest {
@Test
public void exoplayerEffectsPreviewTest_ensuresFirstFrameRendered() throws Exception {
- assumeTrue(Util.SDK_INT >= 18);
-
String testId =
Util.formatInvariant(
"exoplayerEffectsPreviewTest_withPlayWhenReady[%b]_ensuresFirstFrameRendered",
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java
index cc93255206..fe7c3c2d33 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/AudioFocusManager.java
@@ -374,11 +374,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// audio recording or speech recognition'.
// Assistant is considered as both recording and notifying developer
case C.USAGE_ASSISTANT:
- if (Util.SDK_INT >= 19) {
- return AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
- } else {
- return AUDIOFOCUS_GAIN_TRANSIENT;
- }
+ return AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
// Special usages:
case C.USAGE_ASSISTANCE_ACCESSIBILITY:
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java
index 9c822adc38..ff144f9174 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java
@@ -1586,7 +1586,6 @@ public interface ExoPlayer extends Player {
*
* @param videoEffects The {@link List} of {@linkplain Effect video effects} to apply.
*/
- @RequiresApi(18)
@UnstableApi
void setVideoEffects(List This implementation supports pre-acquisition of sessions using {@link
* #preacquireSession(DrmSessionEventListener.EventDispatcher, Format)}.
*/
-@RequiresApi(18)
@UnstableApi
public class DefaultDrmSessionManager implements DrmSessionManager {
@@ -657,11 +655,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
}
private static boolean acquisitionFailedIndicatingResourceShortage(DrmSession session) {
- // ResourceBusyException is only available at API 19, so on earlier versions we
- // assume any error indicates resource shortage (ensuring we retry).
return session.getState() == DrmSession.STATE_ERROR
- && (Util.SDK_INT < 19
- || checkNotNull(session.getError()).getCause() instanceof ResourceBusyException);
+ && checkNotNull(session.getError()).getCause() instanceof ResourceBusyException;
}
/**
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManagerProvider.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManagerProvider.java
index 01a0f78385..e015f93a50 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManagerProvider.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManagerProvider.java
@@ -20,7 +20,6 @@ import static androidx.media3.exoplayer.drm.DefaultDrmSessionManager.MODE_PLAYBA
import androidx.annotation.GuardedBy;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
@@ -75,7 +74,7 @@ public final class DefaultDrmSessionManagerProvider implements DrmSessionManager
checkNotNull(mediaItem.localConfiguration);
@Nullable
MediaItem.DrmConfiguration drmConfiguration = mediaItem.localConfiguration.drmConfiguration;
- if (drmConfiguration == null || Util.SDK_INT < 18) {
+ if (drmConfiguration == null) {
return DrmSessionManager.DRM_UNSUPPORTED;
}
@@ -88,7 +87,6 @@ public final class DefaultDrmSessionManagerProvider implements DrmSessionManager
}
}
- @RequiresApi(18)
private DrmSessionManager createManager(MediaItem.DrmConfiguration drmConfiguration) {
DataSource.Factory dataSourceFactory =
drmHttpDataSourceFactory != null
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DrmUtil.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DrmUtil.java
index d75ca0793d..5da5817446 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DrmUtil.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DrmUtil.java
@@ -80,13 +80,13 @@ public final class DrmUtil {
return Api21.mediaDrmStateExceptionToErrorCode(exception);
} else if (Util.SDK_INT >= 23 && Api23.isMediaDrmResetException(exception)) {
return PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR;
- } else if (Util.SDK_INT >= 18 && Api18.isNotProvisionedException(exception)) {
+ } else if (exception instanceof NotProvisionedException) {
return PlaybackException.ERROR_CODE_DRM_PROVISIONING_FAILED;
- } else if (Util.SDK_INT >= 18 && Api18.isDeniedByServerException(exception)) {
+ } else if (exception instanceof DeniedByServerException) {
return PlaybackException.ERROR_CODE_DRM_DEVICE_REVOKED;
} else if (exception instanceof UnsupportedDrmException) {
return PlaybackException.ERROR_CODE_DRM_SCHEME_UNSUPPORTED;
- } else if (Util.SDK_INT >= 18 && Api18.isMissingSchemeDataException(exception)) {
+ } else if (exception instanceof DefaultDrmSessionManager.MissingSchemeDataException) {
return PlaybackException.ERROR_CODE_DRM_CONTENT_ERROR;
} else if (exception instanceof KeysExpiredException) {
return PlaybackException.ERROR_CODE_DRM_LICENSE_EXPIRED;
@@ -106,25 +106,6 @@ public final class DrmUtil {
// Internal classes.
- @RequiresApi(18)
- private static final class Api18 {
-
- @DoNotInline
- public static boolean isNotProvisionedException(@Nullable Throwable throwable) {
- return throwable instanceof NotProvisionedException;
- }
-
- @DoNotInline
- public static boolean isDeniedByServerException(@Nullable Throwable throwable) {
- return throwable instanceof DeniedByServerException;
- }
-
- @DoNotInline
- public static boolean isMissingSchemeDataException(@Nullable Throwable throwable) {
- return throwable instanceof DefaultDrmSessionManager.MissingSchemeDataException;
- }
- }
-
@RequiresApi(21)
private static final class Api21 {
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DummyExoMediaDrm.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DummyExoMediaDrm.java
index 58efd2f082..d50b0ef827 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DummyExoMediaDrm.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DummyExoMediaDrm.java
@@ -18,7 +18,6 @@ package androidx.media3.exoplayer.drm;
import android.media.MediaDrmException;
import android.os.PersistableBundle;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.C;
import androidx.media3.common.DrmInitData;
import androidx.media3.common.util.UnstableApi;
@@ -29,7 +28,6 @@ import java.util.List;
import java.util.Map;
/** An {@link ExoMediaDrm} that does not support any protection schemes. */
-@RequiresApi(18)
@UnstableApi
public final class DummyExoMediaDrm implements ExoMediaDrm {
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/FrameworkMediaDrm.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/FrameworkMediaDrm.java
index e3d51fffc8..d0a5e48e87 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/FrameworkMediaDrm.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/FrameworkMediaDrm.java
@@ -52,7 +52,6 @@ import java.util.Map;
import java.util.UUID;
/** An {@link ExoMediaDrm} implementation that wraps the framework {@link MediaDrm}. */
-@RequiresApi(18)
public final class FrameworkMediaDrm implements ExoMediaDrm {
private static final String TAG = "FrameworkMediaDrm";
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/OfflineLicenseHelper.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/OfflineLicenseHelper.java
index 6cc5c54733..1e9c0cdd5e 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/OfflineLicenseHelper.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/OfflineLicenseHelper.java
@@ -22,7 +22,6 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.util.Pair;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.DrmInitData;
import androidx.media3.common.Format;
import androidx.media3.common.util.Assertions;
@@ -38,7 +37,6 @@ import java.util.Map;
import java.util.concurrent.ExecutionException;
/** Helper class to download, renew and release offline licenses. */
-@RequiresApi(18)
@UnstableApi
public final class OfflineLicenseHelper {
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecAdapter.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecAdapter.java
index 49c9620f0f..5eb6848320 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecAdapter.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecAdapter.java
@@ -250,7 +250,6 @@ public interface MediaCodecAdapter {
*
* @see MediaCodec#setParameters(Bundle)
*/
- @RequiresApi(19)
void setParameters(Bundle params);
/**
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecBufferEnqueuer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecBufferEnqueuer.java
index 4267b741fd..0e58a8896f 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecBufferEnqueuer.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecBufferEnqueuer.java
@@ -17,7 +17,6 @@ package androidx.media3.exoplayer.mediacodec;
import android.media.MediaCodec;
import android.os.Bundle;
-import androidx.annotation.RequiresApi;
import androidx.media3.decoder.CryptoInfo;
/**
@@ -57,7 +56,6 @@ import androidx.media3.decoder.CryptoInfo;
*
* @see MediaCodec#setParameters(Bundle)
*/
- @RequiresApi(19)
void setParameters(Bundle parameters);
/** Flushes the instance. */
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java
index ee2c1de3cd..ffaefde146 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecInfo.java
@@ -695,11 +695,6 @@ public final class MediaCodecInfo {
}
private static boolean isAdaptive(CodecCapabilities capabilities) {
- return Util.SDK_INT >= 19 && isAdaptiveV19(capabilities);
- }
-
- @RequiresApi(19)
- private static boolean isAdaptiveV19(CodecCapabilities capabilities) {
return capabilities.isFeatureSupported(CodecCapabilities.FEATURE_AdaptivePlayback);
}
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java
index b1f4734871..7225ad0deb 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecRenderer.java
@@ -1217,8 +1217,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecName);
- codecNeedsMonoChannelCountWorkaround =
- codecNeedsMonoChannelCountWorkaround(codecName, checkNotNull(codecInputFormat));
+ codecNeedsMonoChannelCountWorkaround = false;
codecNeedsEosPropagation =
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
if (checkNotNull(codec).needsReconfiguration()) {
@@ -2499,12 +2498,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* @return True if the decoder is known to fail when flushed.
*/
private static boolean codecNeedsFlushWorkaround(String name) {
- return Util.SDK_INT < 18
- || (Util.SDK_INT == 18
- && ("OMX.SEC.avc.dec".equals(name) || "OMX.SEC.avc.dec.secure".equals(name)))
- || (Util.SDK_INT == 19
- && Util.MODEL.startsWith("SM-G800")
- && ("OMX.Exynos.avc.dec".equals(name) || "OMX.Exynos.avc.dec.secure".equals(name)));
+ return Util.SDK_INT == 19
+ && Util.MODEL.startsWith("SM-G800")
+ && ("OMX.Exynos.avc.dec".equals(name) || "OMX.Exynos.avc.dec.secure".equals(name));
}
/**
@@ -2589,7 +2585,6 @@ 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 <= 17 && "OMX.allwinner.video.decoder.avc".equals(name))
|| (Util.SDK_INT <= 29
&& ("OMX.broadcom.video_decoder.tunnel".equals(name)
|| "OMX.broadcom.video_decoder.tunnel.secure".equals(name)
@@ -2615,7 +2610,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
*/
private static boolean codecNeedsEosFlushWorkaround(String name) {
return (Util.SDK_INT <= 23 && "OMX.google.vorbis.decoder".equals(name))
- || (Util.SDK_INT <= 19
+ || (Util.SDK_INT == 19
&& ("hb2000".equals(Util.DEVICE) || "stvm8".equals(Util.DEVICE))
&& ("OMX.amlogic.avc.decoder.awesome".equals(name)
|| "OMX.amlogic.avc.decoder.awesome.secure".equals(name)));
@@ -2654,26 +2649,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return Util.SDK_INT == 21 && "OMX.google.aac.decoder".equals(name);
}
- /**
- * Returns whether the decoder is known to set the number of audio channels in the output {@link
- * Format} to 2 for the given input {@link Format}, whilst only actually outputting a single
- * channel.
- *
- * If true is returned then we explicitly override the number of channels in the output {@link
- * Format}, setting it to 1.
- *
- * @param name The decoder name.
- * @param format The input {@link Format}.
- * @return True if the decoder is known to set the number of audio channels in the output {@link
- * Format} to 2 for the given input {@link Format}, whilst only actually outputting a single
- * channel. False otherwise.
- */
- private static boolean codecNeedsMonoChannelCountWorkaround(String name, Format format) {
- return Util.SDK_INT <= 18
- && format.channelCount == 1
- && "OMX.MTK.AUDIO.DECODER.MP3".equals(name);
- }
-
private static final class OutputStreamInfo {
public static final OutputStreamInfo UNSET =
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java
index fb763d2ad8..aedb35ac03 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/MediaCodecUtil.java
@@ -543,44 +543,6 @@ public final class MediaCodecUtil {
return false;
}
- // Work around https://github.com/google/ExoPlayer/issues/1528 and
- // https://github.com/google/ExoPlayer/issues/3171.
- if (Util.SDK_INT < 18
- && "OMX.MTK.AUDIO.DECODER.AAC".equals(name)
- && ("a70".equals(Util.DEVICE)
- || ("Xiaomi".equals(Util.MANUFACTURER) && Util.DEVICE.startsWith("HM")))) {
- return false;
- }
-
- // Work around an issue where querying/creating a particular MP3 decoder on some devices on
- // platform API version 16 fails.
- if (Util.SDK_INT == 16
- && "OMX.qcom.audio.decoder.mp3".equals(name)
- && ("dlxu".equals(Util.DEVICE) // HTC Butterfly
- || "protou".equals(Util.DEVICE) // HTC Desire X
- || "ville".equals(Util.DEVICE) // HTC One S
- || "villeplus".equals(Util.DEVICE)
- || "villec2".equals(Util.DEVICE)
- || Util.DEVICE.startsWith("gee") // LGE Optimus G
- || "C6602".equals(Util.DEVICE) // Sony Xperia Z
- || "C6603".equals(Util.DEVICE)
- || "C6606".equals(Util.DEVICE)
- || "C6616".equals(Util.DEVICE)
- || "L36h".equals(Util.DEVICE)
- || "SO-02E".equals(Util.DEVICE))) {
- return false;
- }
-
- // Work around an issue where large timestamps are not propagated correctly.
- if (Util.SDK_INT == 16
- && "OMX.qcom.audio.decoder.aac".equals(name)
- && ("C1504".equals(Util.DEVICE) // Sony Xperia E
- || "C1505".equals(Util.DEVICE)
- || "C1604".equals(Util.DEVICE) // Sony Xperia E dual
- || "C1605".equals(Util.DEVICE))) {
- return false;
- }
-
// Work around https://github.com/google/ExoPlayer/issues/3249.
if (Util.SDK_INT < 24
&& ("OMX.SEC.aac.dec".equals(name) || "OMX.Exynos.AAC.Decoder".equals(name))
@@ -598,7 +560,7 @@ public final class MediaCodecUtil {
// Work around https://github.com/google/ExoPlayer/issues/548.
// VP8 decoder on Samsung Galaxy S3/S4/S4 Mini/Tab 3/Note 2 does not render video.
- if (Util.SDK_INT <= 19
+ if (Util.SDK_INT == 19
&& "OMX.SEC.vp8.dec".equals(name)
&& "samsung".equals(Util.MANUFACTURER)
&& (Util.DEVICE.startsWith("d2")
@@ -610,7 +572,7 @@ public final class MediaCodecUtil {
}
// VP8 decoder on Samsung Galaxy S4 cannot be queried.
- if (Util.SDK_INT <= 19
+ if (Util.SDK_INT == 19
&& Util.DEVICE.startsWith("jflte")
&& "OMX.qcom.video.decoder.vp8".equals(name)) {
return false;
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/SynchronousMediaCodecAdapter.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/SynchronousMediaCodecAdapter.java
index 1d5d4cb27d..d45a6d5035 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/SynchronousMediaCodecAdapter.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/SynchronousMediaCodecAdapter.java
@@ -192,7 +192,6 @@ public final class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
}
@Override
- @RequiresApi(19)
public void setParameters(Bundle params) {
codec.setParameters(params);
}
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java
index dca7777385..95e67501da 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java
@@ -715,7 +715,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
}
}
- @TargetApi(17) // Needed for placeholderSurface usage, as it is always null on API level 16.
@Override
protected void onReset() {
try {
@@ -804,7 +803,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
} else {
MediaCodecInfo codecInfo = getCodecInfo();
if (codecInfo != null && shouldUsePlaceholderSurface(codecInfo)) {
- placeholderSurface = PlaceholderSurface.newInstanceV17(context, codecInfo.secure);
+ placeholderSurface = PlaceholderSurface.newInstance(context, codecInfo.secure);
displaySurface = placeholderSurface;
}
}
@@ -866,7 +865,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
return tunneling && Util.SDK_INT < 23;
}
- @TargetApi(17) // Needed for placeHolderSurface usage, as it is always null on API level 16.
@Override
protected MediaCodecAdapter.Configuration getMediaCodecConfiguration(
MediaCodecInfo codecInfo,
@@ -892,7 +890,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
throw new IllegalStateException();
}
if (placeholderSurface == null) {
- placeholderSurface = PlaceholderSurface.newInstanceV17(context, codecInfo.secure);
+ placeholderSurface = PlaceholderSurface.newInstance(context, codecInfo.secure);
}
displaySurface = placeholderSurface;
}
@@ -1682,7 +1680,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
&& (!codecInfo.secure || PlaceholderSurface.isSecureSupported(context));
}
- @RequiresApi(17)
private void releasePlaceholderSurface() {
if (displaySurface == placeholderSurface) {
displaySurface = null;
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaceholderSurface.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaceholderSurface.java
index 5ee73d52f6..fb133567f4 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaceholderSurface.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaceholderSurface.java
@@ -26,7 +26,6 @@ import android.os.HandlerThread;
import android.os.Message;
import android.view.Surface;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.EGLSurfaceTexture;
import androidx.media3.common.util.EGLSurfaceTexture.SecureMode;
@@ -34,10 +33,10 @@ 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.errorprone.annotations.InlineMe;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** A placeholder {@link Surface}. */
-@RequiresApi(17)
@UnstableApi
public final class PlaceholderSurface extends Surface {
@@ -66,6 +65,17 @@ public final class PlaceholderSurface extends Surface {
return secureMode != SECURE_MODE_NONE;
}
+ /**
+ * @deprecated Use {@link #newInstance(Context, boolean)} instead.
+ */
+ @InlineMe(
+ replacement = "PlaceholderSurface.newInstance(context, secure)",
+ imports = "androidx.media3.exoplayer.video.PlaceholderSurface")
+ @Deprecated
+ public static PlaceholderSurface newInstanceV17(Context context, boolean secure) {
+ return newInstance(context, secure);
+ }
+
/**
* Returns a newly created placeholder surface. The surface must be released by calling {@link
* #release} when it's no longer required.
@@ -78,7 +88,7 @@ public final class PlaceholderSurface extends Surface {
* @throws IllegalStateException If a secure surface is requested on a device for which {@link
* #isSecureSupported(Context)} returns {@code false}.
*/
- public static PlaceholderSurface newInstanceV17(Context context, boolean secure) {
+ public static PlaceholderSurface newInstance(Context context, boolean secure) {
Assertions.checkState(!secure || isSecureSupported(context));
PlaceholderSurfaceThread thread = new PlaceholderSurfaceThread();
return thread.init(secure ? secureMode : SECURE_MODE_NONE);
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoFrameReleaseHelper.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoFrameReleaseHelper.java
index 6c1255c9fa..10dc0bdca2 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoFrameReleaseHelper.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoFrameReleaseHelper.java
@@ -26,7 +26,6 @@ import android.view.Choreographer;
import android.view.Choreographer.FrameCallback;
import android.view.Display;
import android.view.Surface;
-import android.view.WindowManager;
import androidx.annotation.DoNotInline;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
@@ -161,7 +160,7 @@ public final class VideoFrameReleaseHelper {
resetAdjustment();
if (displayHelper != null) {
checkNotNull(vsyncSampler).addObserver();
- displayHelper.register(this::updateDefaultDisplayRefreshRateParams);
+ displayHelper.register();
}
updateSurfacePlaybackFrameRate(/* forceUpdate= */ false);
}
@@ -172,7 +171,7 @@ public final class VideoFrameReleaseHelper {
* @param surface The new {@link Surface}, or {@code null} if the renderer does not have one.
*/
public void onSurfaceChanged(@Nullable Surface surface) {
- if (Util.SDK_INT >= 17 && Api17.isPlaceholderSurface(surface)) {
+ if (surface instanceof PlaceholderSurface) {
// We don't care about dummy surfaces for release timing, since they're not visible.
surface = null;
}
@@ -418,18 +417,13 @@ public final class VideoFrameReleaseHelper {
}
@Nullable
- private static DisplayHelper maybeBuildDisplayHelper(@Nullable Context context) {
- @Nullable DisplayHelper displayHelper = null;
- if (context != null) {
- context = context.getApplicationContext();
- if (Util.SDK_INT >= 17) {
- displayHelper = DisplayHelperV17.maybeBuildNewInstance(context);
- }
- if (displayHelper == null) {
- displayHelper = DisplayHelperV16.maybeBuildNewInstance(context);
- }
+ private DisplayHelper maybeBuildDisplayHelper(@Nullable Context context) {
+ if (context == null) {
+ return null;
}
- return displayHelper;
+ DisplayManager displayManager =
+ (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+ return displayManager != null ? new DisplayHelper(displayManager) : null;
}
// Nested classes.
@@ -450,92 +444,27 @@ public final class VideoFrameReleaseHelper {
}
}
- /** Helper for listening to changes to the default display. */
- private interface DisplayHelper {
-
- /** Listener for changes to the default display. */
- interface Listener {
-
- /**
- * Called when the default display changes.
- *
- * @param defaultDisplay The default display, or {@code null} if a corresponding {@link
- * Display} object could not be obtained.
- */
- void onDefaultDisplayChanged(@Nullable Display defaultDisplay);
- }
-
- /**
- * Enables the helper, invoking {@link Listener#onDefaultDisplayChanged(Display)} to pass the
- * initial default display.
- */
- void register(Listener listener);
-
- /** Disables the helper. */
- void unregister();
- }
-
- private static final class DisplayHelperV16 implements DisplayHelper {
-
- @Nullable
- public static DisplayHelper maybeBuildNewInstance(Context context) {
- WindowManager windowManager =
- (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- return windowManager != null ? new DisplayHelperV16(windowManager) : null;
- }
-
- private final WindowManager windowManager;
-
- private DisplayHelperV16(WindowManager windowManager) {
- this.windowManager = windowManager;
- }
-
- @Override
- public void register(Listener listener) {
- listener.onDefaultDisplayChanged(windowManager.getDefaultDisplay());
- }
-
- @Override
- public void unregister() {
- // Do nothing.
- }
- }
-
- @RequiresApi(17)
- private static final class DisplayHelperV17
- implements DisplayHelper, DisplayManager.DisplayListener {
-
- @Nullable
- public static DisplayHelper maybeBuildNewInstance(Context context) {
- DisplayManager displayManager =
- (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
- return displayManager != null ? new DisplayHelperV17(displayManager) : null;
- }
+ private final class DisplayHelper implements DisplayManager.DisplayListener {
private final DisplayManager displayManager;
- @Nullable private Listener listener;
- private DisplayHelperV17(DisplayManager displayManager) {
+ public DisplayHelper(DisplayManager displayManager) {
this.displayManager = displayManager;
}
- @Override
- public void register(Listener listener) {
- this.listener = listener;
+ public void register() {
displayManager.registerDisplayListener(this, Util.createHandlerForCurrentLooper());
- listener.onDefaultDisplayChanged(getDefaultDisplay());
+ updateDefaultDisplayRefreshRateParams(getDefaultDisplay());
}
- @Override
public void unregister() {
displayManager.unregisterDisplayListener(this);
- listener = null;
}
@Override
public void onDisplayChanged(int displayId) {
- if (listener != null && displayId == Display.DEFAULT_DISPLAY) {
- listener.onDefaultDisplayChanged(getDefaultDisplay());
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ updateDefaultDisplayRefreshRateParams(getDefaultDisplay());
}
}
@@ -653,13 +582,4 @@ public final class VideoFrameReleaseHelper {
}
}
}
-
- @RequiresApi(17)
- private static final class Api17 {
-
- @DoNotInline
- public static boolean isPlaceholderSurface(@Nullable Surface surface) {
- return surface instanceof PlaceholderSurface;
- }
- }
}
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java
index b351c6c76e..ad268a0aaa 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/spherical/SphericalGLSurfaceView.java
@@ -39,7 +39,6 @@ import androidx.media3.common.C;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.UnstableApi;
-import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.video.VideoFrameMetadataListener;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.microedition.khronos.egl.EGLConfig;
@@ -103,14 +102,12 @@ public final class SphericalGLSurfaceView extends GLSurfaceView {
// Configure sensors and touch.
sensorManager =
(SensorManager) Assertions.checkNotNull(context.getSystemService(Context.SENSOR_SERVICE));
- @Nullable Sensor orientationSensor = null;
- if (Util.SDK_INT >= 18) {
- // TYPE_GAME_ROTATION_VECTOR is the easiest sensor since it handles all the complex math for
- // fusion. It's used instead of TYPE_ROTATION_VECTOR since the latter uses the magnetometer on
- // devices. When used indoors, the magnetometer can take some time to settle depending on the
- // device and amount of metal in the environment.
- orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
- }
+ // TYPE_GAME_ROTATION_VECTOR is the easiest sensor since it handles all the complex math for
+ // fusion. It's used instead of TYPE_ROTATION_VECTOR since the latter uses the magnetometer on
+ // devices. When used indoors, the magnetometer can take some time to settle depending on the
+ // device and amount of metal in the environment.
+ @Nullable
+ Sensor orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
if (orientationSensor == null) {
orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
}
diff --git a/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java b/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java
index 72d7d31127..b1f0e82a5c 100644
--- a/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java
+++ b/libraries/session/src/main/java/androidx/media3/session/ConnectionState.java
@@ -26,7 +26,6 @@ import androidx.core.app.BundleCompat;
import androidx.media3.common.Bundleable;
import androidx.media3.common.Player;
import androidx.media3.common.util.BundleCollectionUtil;
-import androidx.media3.common.util.BundleUtil;
import androidx.media3.common.util.Util;
import com.google.common.collect.ImmutableList;
import java.util.List;
@@ -139,7 +138,7 @@ import java.util.List;
*/
public Bundle toBundleInProcess() {
Bundle bundle = new Bundle();
- BundleUtil.putBinder(bundle, FIELD_IN_PROCESS_BINDER, new InProcessBinder());
+ bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
return bundle;
}
@@ -152,7 +151,7 @@ import java.util.List;
/** Restores a {@code ConnectionState} from a {@link Bundle}. */
public static ConnectionState fromBundle(Bundle bundle) {
- @Nullable IBinder inProcessBinder = BundleUtil.getBinder(bundle, FIELD_IN_PROCESS_BINDER);
+ @Nullable IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
if (inProcessBinder instanceof InProcessBinder) {
return ((InProcessBinder) inProcessBinder).getConnectionState();
}
diff --git a/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java b/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java
index 53b12ca12c..2683071ae2 100644
--- a/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java
+++ b/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java
@@ -47,7 +47,6 @@ import androidx.media3.common.Tracks;
import androidx.media3.common.VideoSize;
import androidx.media3.common.text.CueGroup;
import androidx.media3.common.util.Assertions;
-import androidx.media3.common.util.BundleUtil;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.common.base.Objects;
@@ -901,7 +900,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
*/
public Bundle toBundleInProcess() {
Bundle bundle = new Bundle();
- BundleUtil.putBinder(bundle, FIELD_IN_PROCESS_BINDER, new InProcessBinder());
+ bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
return bundle;
}
@@ -1025,7 +1024,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
/** Restores a {@code PlayerInfo} from a {@link Bundle}. */
public static PlayerInfo fromBundle(Bundle bundle) {
- @Nullable IBinder inProcessBinder = BundleUtil.getBinder(bundle, FIELD_IN_PROCESS_BINDER);
+ @Nullable IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
if (inProcessBinder instanceof InProcessBinder) {
return ((InProcessBinder) inProcessBinder).getPlayerInfo();
}
diff --git a/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/DashTestRunner.java b/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/DashTestRunner.java
index 6daa365853..3a3a6a3a32 100644
--- a/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/DashTestRunner.java
+++ b/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/DashTestRunner.java
@@ -21,7 +21,6 @@ import android.media.MediaDrm;
import android.media.UnsupportedSchemeException;
import android.view.Surface;
import android.widget.FrameLayout;
-import androidx.annotation.RequiresApi;
import androidx.annotation.Size;
import androidx.media3.common.C;
import androidx.media3.common.Format;
@@ -106,22 +105,17 @@ import java.util.List;
@SuppressWarnings("ResourceType")
public static boolean isL1WidevineAvailable(String mimeType) {
- if (Util.SDK_INT >= 18) {
- try {
- // Force L3 if secure decoder is not available.
- if (MediaCodecUtil.getDecoderInfo(mimeType, /* secure= */ true, /* tunneling= */ false)
- == null) {
- return false;
- }
- MediaDrm mediaDrm = MediaDrmBuilder.build();
- String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
- mediaDrm.release();
- return WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty);
- } catch (MediaCodecUtil.DecoderQueryException e) {
- throw new IllegalStateException(e);
+ try (MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID)) {
+ // Force L3 if secure decoder is not available.
+ if (MediaCodecUtil.getDecoderInfo(mimeType, /* secure= */ true, /* tunneling= */ false)
+ == null) {
+ return false;
}
+ String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
+ return WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty);
+ } catch (UnsupportedSchemeException | MediaCodecUtil.DecoderQueryException e) {
+ throw new IllegalStateException(e);
}
- return false;
}
public DashTestRunner(@Size(max = 23) String tag, HostActivity activity) {
@@ -507,20 +501,4 @@ import java.util.List;
return RendererCapabilities.getFormatSupport(formatSupport) == C.FORMAT_HANDLED;
}
}
-
- /**
- * Creates a new {@code MediaDrm} object. The encapsulation ensures that the tests can be executed
- * for API level < 18.
- */
- @RequiresApi(18)
- private static final class MediaDrmBuilder {
-
- public static MediaDrm build() {
- try {
- return new MediaDrm(WIDEVINE_UUID);
- } catch (UnsupportedSchemeException e) {
- throw new IllegalStateException(e);
- }
- }
- }
}
diff --git a/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/EnumerateDecodersTest.java b/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/EnumerateDecodersTest.java
index 750d47e16e..742e835e1f 100644
--- a/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/EnumerateDecodersTest.java
+++ b/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/EnumerateDecodersTest.java
@@ -135,8 +135,7 @@ public class EnumerateDecodersTest {
appendAudioCapabilities(codecCapabilities.getAudioCapabilities(), result);
}
}
- if (Util.SDK_INT >= 19
- && isVideo
+ if (isVideo
&& codecCapabilities.isFeatureSupported(CodecCapabilities.FEATURE_AdaptivePlayback)) {
result.append(", FEATURE_AdaptivePlayback");
}
diff --git a/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/GtsTestUtil.java b/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/GtsTestUtil.java
index a78f60371d..c1ff1fff30 100644
--- a/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/GtsTestUtil.java
+++ b/libraries/test_exoplayer_playback/src/androidTest/java/androidx/media3/test/exoplayer/playback/gts/GtsTestUtil.java
@@ -21,7 +21,6 @@ import static androidx.media3.common.C.WIDEVINE_UUID;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaDrm;
-import androidx.media3.common.util.Util;
/** Utility methods for GTS tests. */
public final class GtsTestUtil {
@@ -30,10 +29,6 @@ public final class GtsTestUtil {
/** Returns true if the device doesn't support Widevine and this is permitted. */
public static boolean shouldSkipWidevineTest(Context context) {
- if (Util.SDK_INT < 18) {
- // MediaDrm isn't present until API 18
- return true;
- }
if (isGmsInstalled(context)) {
// GMS devices are required to support Widevine.
return false;
diff --git a/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/HandlerThreadTestRule.java b/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/HandlerThreadTestRule.java
index 15031974c2..02e84be4b5 100644
--- a/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/HandlerThreadTestRule.java
+++ b/libraries/test_session_common/src/main/java/androidx/media3/test/session/common/HandlerThreadTestRule.java
@@ -16,7 +16,6 @@
package androidx.media3.test.session.common;
import android.os.HandlerThread;
-import androidx.media3.common.util.Util;
import org.junit.rules.ExternalResource;
/** TestRule for providing a handler and an executor for {@link HandlerThread}. */
@@ -40,11 +39,7 @@ public final class HandlerThreadTestRule extends ExternalResource {
@Override
protected void after() {
try {
- if (Util.SDK_INT >= 18) {
- handler.getLooper().quitSafely();
- } else {
- handler.getLooper().quit();
- }
+ handler.getLooper().quitSafely();
} finally {
handler = null;
}
diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java
index dd5c28079c..8738707fa7 100644
--- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java
+++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerTest.java
@@ -57,7 +57,6 @@ import androidx.media3.common.TrackSelectionOverride;
import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.Tracks;
import androidx.media3.common.VideoSize;
-import androidx.media3.common.util.Util;
import androidx.media3.test.session.R;
import androidx.media3.test.session.common.HandlerThreadTestRule;
import androidx.media3.test.session.common.MainLooperTestRule;
@@ -163,13 +162,10 @@ public class MediaControllerTest {
MediaController controller = controllerTestRule.createController(session.getToken());
PendingIntent sessionActivity = controller.getSessionActivity();
assertThat(sessionActivity).isNotNull();
- if (Util.SDK_INT >= 17) {
- // PendingIntent#getCreatorPackage() is added in API 17.
- assertThat(sessionActivity.getCreatorPackage()).isEqualTo(SUPPORT_APP_PACKAGE_NAME);
+ assertThat(sessionActivity.getCreatorPackage()).isEqualTo(SUPPORT_APP_PACKAGE_NAME);
- // TODO: Add getPid/getUid in MediaControllerProviderService and compare them.
- // assertThat(sessionActivity.getCreatorUid()).isEqualTo(remoteSession.getUid());
- }
+ // TODO: Add getPid/getUid in MediaControllerProviderService and compare them.
+ // assertThat(sessionActivity.getCreatorUid()).isEqualTo(remoteSession.getUid());
session.cleanUp();
}
diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithFrameworkMediaSessionTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithFrameworkMediaSessionTest.java
index 4bc559a762..0af19ddefb 100644
--- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithFrameworkMediaSessionTest.java
+++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithFrameworkMediaSessionTest.java
@@ -71,11 +71,7 @@ public class MediaControllerWithFrameworkMediaSessionTest {
@After
public void cleanUp() {
if (handler != null) {
- if (Util.SDK_INT >= 18) {
- handler.getLooper().quitSafely();
- } else {
- handler.getLooper().quit();
- }
+ handler.getLooper().quitSafely();
handler = null;
}
}
diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithMediaSessionCompatTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithMediaSessionCompatTest.java
index c91be5d5b2..3f205b6f63 100644
--- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithMediaSessionCompatTest.java
+++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaControllerWithMediaSessionCompatTest.java
@@ -371,10 +371,7 @@ public class MediaControllerWithMediaSessionCompatTest {
MediaController controller = controllerTestRule.createController(session.getSessionToken());
PendingIntent sessionActivityOut = controller.getSessionActivity();
assertThat(sessionActivityOut).isNotNull();
- if (Util.SDK_INT >= 17) {
- // PendingIntent#getCreatorPackage() is added in API 17.
- assertThat(sessionActivityOut.getCreatorPackage()).isEqualTo(context.getPackageName());
- }
+ assertThat(sessionActivityOut.getCreatorPackage()).isEqualTo(context.getPackageName());
}
@Test
diff --git a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java
index be892ff162..4d9dd28068 100644
--- a/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java
+++ b/libraries/test_session_current/src/androidTest/java/androidx/media3/session/MediaSessionTest.java
@@ -379,11 +379,7 @@ public class MediaSessionTest {
});
}
- if (Util.SDK_INT >= 18) {
- testThread.quitSafely();
- } else {
- testThread.quit();
- }
+ testThread.quitSafely();
}
}
diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java
index 1f90c68609..dc72a77ccc 100644
--- a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java
+++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaLibraryService.java
@@ -186,11 +186,7 @@ public class MockMediaLibraryService extends MediaLibraryService {
expectedParams = null;
}
TestServiceRegistry.getInstance().cleanUp();
- if (Util.SDK_INT >= 18) {
- handlerThread.quitSafely();
- } else {
- handlerThread.quit();
- }
+ handlerThread.quitSafely();
}
@Override
diff --git a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaSessionService.java b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaSessionService.java
index 12d271716a..3b31210e96 100644
--- a/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaSessionService.java
+++ b/libraries/test_session_current/src/main/java/androidx/media3/session/MockMediaSessionService.java
@@ -23,7 +23,6 @@ import android.os.IBinder;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.media3.common.util.ConditionVariable;
-import androidx.media3.common.util.Util;
import androidx.media3.session.MediaSession.ControllerInfo;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
@@ -91,11 +90,7 @@ public class MockMediaSessionService extends MediaSessionService {
public void onDestroy() {
super.onDestroy();
TestServiceRegistry.getInstance().cleanUp();
- if (Util.SDK_INT >= 18) {
- handlerThread.quitSafely();
- } else {
- handlerThread.quit();
- }
+ handlerThread.quitSafely();
}
@Override
diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/AdditionalFailureInfo.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/AdditionalFailureInfo.java
index 8f4ee1cb21..64497966ae 100644
--- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/AdditionalFailureInfo.java
+++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/AdditionalFailureInfo.java
@@ -16,7 +16,6 @@
package androidx.media3.test.utils;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.util.NullableType;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
@@ -39,7 +38,6 @@ import org.junit.runners.model.Statement;
* Includes special handling for {@link AssertionError} to ensure that test failures are
* correctly distinguished from test errors (all other errors/exceptions).
*/
-@RequiresApi(19)
@UnstableApi
public final class AdditionalFailureInfo implements TestRule {
diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/BitmapPixelTestUtil.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/BitmapPixelTestUtil.java
index d35e5a7e32..1610103144 100644
--- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/BitmapPixelTestUtil.java
+++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/BitmapPixelTestUtil.java
@@ -145,7 +145,6 @@ public class BitmapPixelTestUtil {
* @return A {@link Bitmap}.
* @throws IOException If the bitmap can't be read.
*/
- @RequiresApi(19) // BitmapFactory.Options#inPremultiplied.
public static Bitmap readBitmapUnpremultipliedAlpha(String assetString) throws IOException {
Bitmap bitmap;
try (InputStream inputStream = getApplicationContext().getAssets().open(assetString)) {
@@ -161,7 +160,6 @@ public class BitmapPixelTestUtil {
* Returns a bitmap with the same information as the provided alpha/red/green/blue 8-bits per
* component image.
*/
- @RequiresApi(19)
public static Bitmap createArgb8888BitmapFromRgba8888Image(Image image) {
int width = image.getWidth();
int height = image.getHeight();
@@ -186,7 +184,6 @@ public class BitmapPixelTestUtil {
/**
* Returns a grayscale bitmap from the Luma channel in the {@link ImageFormat#YUV_420_888} image.
*/
- @RequiresApi(19)
public static Bitmap createGrayscaleArgb8888BitmapFromYuv420888Image(Image image) {
int width = image.getWidth();
int height = image.getHeight();
@@ -423,7 +420,6 @@ public class BitmapPixelTestUtil {
// createUnpremultipliedArgb8888BitmapFromFocusedGlFramebuffer back to
// createArgb8888BitmapFromFocusedGlFramebuffer. Also, apply
// setPremultiplied(false) to createBitmapFromFocusedGlFrameBuffer.
- @RequiresApi(17) // #flipBitmapVertically.
public static Bitmap createArgb8888BitmapFromFocusedGlFramebuffer(int width, int height)
throws GlUtil.GlException {
return createBitmapFromFocusedGlFrameBuffer(
@@ -440,7 +436,6 @@ public class BitmapPixelTestUtil {
* @param height The height of the pixel rectangle to read.
* @return A {@link Bitmap} with the framebuffer's values.
*/
- @RequiresApi(19) // Bitmap#setPremultiplied.
public static Bitmap createUnpremultipliedArgb8888BitmapFromFocusedGlFramebuffer(
int width, int height) throws GlUtil.GlException {
Bitmap bitmap =
@@ -471,7 +466,6 @@ public class BitmapPixelTestUtil {
width, height, /* pixelSize= */ 8, GLES30.GL_HALF_FLOAT, Bitmap.Config.RGBA_F16);
}
- @RequiresApi(17) // #flipBitmapVertically.
private static Bitmap createBitmapFromFocusedGlFrameBuffer(
int width, int height, int pixelSize, int glReadPixelsFormat, Bitmap.Config bitmapConfig)
throws GlUtil.GlException {
@@ -494,14 +488,12 @@ public class BitmapPixelTestUtil {
* @param bitmap A {@link Bitmap}.
* @return The identifier of the newly created texture.
*/
- @RequiresApi(17) // #flipBitmapVertically.
public static int createGlTextureFromBitmap(Bitmap bitmap) throws GlUtil.GlException {
// Put the flipped bitmap in the OpenGL texture as the bitmap's positive y-axis points down
// while OpenGL's positive y-axis points up.
return GlUtil.createTexture(flipBitmapVertically(bitmap));
}
- @RequiresApi(17) // Bitmap#isPremultiplied.
public static Bitmap flipBitmapVertically(Bitmap bitmap) {
boolean wasPremultiplied = bitmap.isPremultiplied();
if (!wasPremultiplied) {
diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/CapturingRenderersFactory.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/CapturingRenderersFactory.java
index 1be920f8f5..d11aa70432 100644
--- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/CapturingRenderersFactory.java
+++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/CapturingRenderersFactory.java
@@ -174,7 +174,6 @@ public class CapturingRenderersFactory implements RenderersFactory, Dumper.Dumpa
constructedAdapters = new ArrayList<>();
}
- @RequiresApi(18)
@Override
public MediaCodecAdapter createAdapter(Configuration configuration) throws IOException {
CapturingMediaCodecAdapter adapter =
@@ -343,7 +342,6 @@ public class CapturingRenderersFactory implements RenderersFactory, Dumper.Dumpa
delegate.setOutputSurface(surface);
}
- @RequiresApi(19)
@Override
public void setParameters(Bundle params) {
delegate.setParameters(params);
diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/DataSourceContractTest.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/DataSourceContractTest.java
index bc483fdfe9..c9db9dc5cb 100644
--- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/DataSourceContractTest.java
+++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/DataSourceContractTest.java
@@ -31,7 +31,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.net.Uri;
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;
@@ -68,7 +67,6 @@ import org.mockito.Mockito;
* not required) to also annotate this {@link Ignore @Ignore} so that JUnit correctly reports the
* test as skipped/ignored instead of passing.
*/
-@RequiresApi(19)
@UnstableApi
public abstract class DataSourceContractTest {
diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/HttpDataSourceTestEnv.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/HttpDataSourceTestEnv.java
index 48ae08e1f3..dad7531277 100644
--- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/HttpDataSourceTestEnv.java
+++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/HttpDataSourceTestEnv.java
@@ -19,7 +19,6 @@ package androidx.media3.test.utils;
import static androidx.media3.test.utils.WebServerDispatcher.getRequestPath;
import android.net.Uri;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.HttpDataSource;
import com.google.common.collect.ImmutableList;
@@ -32,7 +31,6 @@ import org.junit.Rule;
import org.junit.rules.ExternalResource;
/** A JUnit {@link Rule} that creates test resources for {@link HttpDataSource} contract tests. */
-@RequiresApi(19)
@UnstableApi
public class HttpDataSourceTestEnv extends ExternalResource {
private static int seed = 0;
diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/TextureBitmapReader.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/TextureBitmapReader.java
index 3ff86df499..042c92cf46 100644
--- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/TextureBitmapReader.java
+++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/TextureBitmapReader.java
@@ -23,7 +23,6 @@ import android.graphics.Bitmap;
import android.os.Build;
import android.view.Surface;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.VideoFrameProcessingException;
import androidx.media3.common.util.GlUtil;
@@ -93,7 +92,6 @@ public final class TextureBitmapReader implements VideoFrameProcessorTestRunner.
// createArgb8888BitmapFromFocusedGlFramebuffer, so that TextureBitmapReader always reads bitmaps
// as unpremultiplied alpha. Then, remove this method (as we'll already be using premultiplied
// alpha).
- @RequiresApi(17) // BitmapPixelTestUtil#createArgb8888BitmapFromFocusedGlFramebuffer.
public void readBitmap(GlTextureInfo outputTexture, long presentationTimeUs)
throws VideoFrameProcessingException {
try {
@@ -114,7 +112,6 @@ public final class TextureBitmapReader implements VideoFrameProcessorTestRunner.
* The read result can be fetched by calling {@link #getBitmapAtPresentationTimeUs} or {@link
* #getBitmap}.
*/
- @RequiresApi(19) // BitmapPixelTestUtil#createArgb8888BitmapFromFocusedGlFramebuffer.
public void readBitmapUnpremultipliedAlpha(GlTextureInfo outputTexture, long presentationTimeUs)
throws VideoFrameProcessingException {
checkState(!useHighPrecisionColorComponents);
@@ -130,7 +127,6 @@ public final class TextureBitmapReader implements VideoFrameProcessorTestRunner.
}
}
- @RequiresApi(17) // BitmapPixelTestUtil#createArgb8888BitmapFromFocusedGlFramebuffer.
private static Bitmap createBitmapFromCurrentGlFrameBuffer(
int width, int height, boolean useHighPrecisionColorComponents) throws GlUtil.GlException {
if (!useHighPrecisionColorComponents) {
diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/VideoFrameProcessorTestRunner.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/VideoFrameProcessorTestRunner.java
index 8c6a6e94a9..5481badb4b 100644
--- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/VideoFrameProcessorTestRunner.java
+++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/VideoFrameProcessorTestRunner.java
@@ -35,7 +35,6 @@ import android.media.MediaFormat;
import android.util.Pair;
import android.view.Surface;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.media3.common.ColorInfo;
import androidx.media3.common.DebugViewProvider;
import androidx.media3.common.Effect;
@@ -61,7 +60,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** A test runner for {@link VideoFrameProcessor} tests. */
@UnstableApi
-@RequiresApi(19)
public final class VideoFrameProcessorTestRunner {
/** A builder for {@link VideoFrameProcessorTestRunner} instances. */
diff --git a/libraries/test_utils_robolectric/src/main/java/androidx/media3/test/utils/robolectric/ShadowMediaCodecConfig.java b/libraries/test_utils_robolectric/src/main/java/androidx/media3/test/utils/robolectric/ShadowMediaCodecConfig.java
index 13b3fd378a..468cecefe8 100644
--- a/libraries/test_utils_robolectric/src/main/java/androidx/media3/test/utils/robolectric/ShadowMediaCodecConfig.java
+++ b/libraries/test_utils_robolectric/src/main/java/androidx/media3/test/utils/robolectric/ShadowMediaCodecConfig.java
@@ -77,8 +77,8 @@ public final class ShadowMediaCodecConfig extends ExternalResource {
@Override
protected void before() throws Throwable {
- if (Util.SDK_INT <= 19) {
- // Codec config not supported with Robolectric on API <= 19. Skip rule set up step.
+ if (Util.SDK_INT == 19) {
+ // Codec config not supported with Robolectric on API == 19. Skip rule set up step.
return;
}
configureCodecs(supportedMimeTypes);
@@ -88,8 +88,8 @@ public final class ShadowMediaCodecConfig extends ExternalResource {
protected void after() {
supportedMimeTypes.clear();
MediaCodecUtil.clearDecoderInfoCache();
- if (Util.SDK_INT <= 19) {
- // Codec config not supported with Robolectric on API <= 19. Skip rule tear down step.
+ if (Util.SDK_INT == 19) {
+ // Codec config not supported with Robolectric on API == 19. Skip rule tear down step.
return;
}
ShadowMediaCodecList.reset();
diff --git a/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java b/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java
index 3f1e8507aa..834e1e4063 100644
--- a/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java
+++ b/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java
@@ -114,15 +114,18 @@ public final class CaptionStyleCompat {
* @param captionStyle A {@link CaptionStyle}.
* @return The equivalent {@link CaptionStyleCompat}.
*/
- @RequiresApi(19)
public static CaptionStyleCompat createFromCaptionStyle(
CaptioningManager.CaptionStyle captionStyle) {
if (Util.SDK_INT >= 21) {
return createFromCaptionStyleV21(captionStyle);
} else {
- // Note - Any caller must be on at least API level 19 or greater (because CaptionStyle did
- // not exist in earlier API levels).
- return createFromCaptionStyleV19(captionStyle);
+ return new CaptionStyleCompat(
+ captionStyle.foregroundColor,
+ captionStyle.backgroundColor,
+ Color.TRANSPARENT,
+ captionStyle.edgeType,
+ captionStyle.edgeColor,
+ captionStyle.getTypeface());
}
}
@@ -149,19 +152,6 @@ public final class CaptionStyleCompat {
this.typeface = typeface;
}
- @RequiresApi(19)
- @SuppressWarnings("ResourceType")
- private static CaptionStyleCompat createFromCaptionStyleV19(
- CaptioningManager.CaptionStyle captionStyle) {
- return new CaptionStyleCompat(
- captionStyle.foregroundColor,
- captionStyle.backgroundColor,
- Color.TRANSPARENT,
- captionStyle.edgeType,
- captionStyle.edgeColor,
- captionStyle.getTypeface());
- }
-
@RequiresApi(21)
@SuppressWarnings("ResourceType")
private static CaptionStyleCompat createFromCaptionStyleV21(
diff --git a/libraries/ui/src/main/java/androidx/media3/ui/SubtitleView.java b/libraries/ui/src/main/java/androidx/media3/ui/SubtitleView.java
index 6e7285da64..a4a891bdf8 100644
--- a/libraries/ui/src/main/java/androidx/media3/ui/SubtitleView.java
+++ b/libraries/ui/src/main/java/androidx/media3/ui/SubtitleView.java
@@ -33,7 +33,6 @@ import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.media3.common.text.Cue;
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;
@@ -319,7 +318,7 @@ public final class SubtitleView extends FrameLayout {
}
private float getUserCaptionFontScale() {
- if (Util.SDK_INT < 19 || isInEditMode()) {
+ if (isInEditMode()) {
return 1f;
}
@Nullable
@@ -331,7 +330,7 @@ public final class SubtitleView extends FrameLayout {
}
private CaptionStyleCompat getUserCaptionStyle() {
- if (Util.SDK_INT < 19 || isInEditMode()) {
+ if (isInEditMode()) {
return CaptionStyleCompat.DEFAULT;
}
@Nullable