From 973b71791477680d772323df8f45885fc93b3aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Tue, 16 Jan 2024 11:17:29 +0100 Subject: [PATCH 01/12] Remove unnecessary `SDK_INT` checks --- .../androidx/media3/demo/gl/MainActivity.java | 2 +- .../media3/demo/main/DownloadTracker.java | 7 -- .../media3/demo/main/PlayerActivity.java | 6 +- demos/main/src/main/res/values/strings.xml | 2 - .../java/androidx/media3/common/Timeline.java | 9 +- .../common/TrackSelectionParameters.java | 6 +- .../media3/common/util/BundleUtil.java | 112 ------------------ .../media3/common/util/EGLSurfaceTexture.java | 5 +- .../androidx/media3/common/util/GlUtil.java | 25 ++-- .../media3/common/util/TraceUtil.java | 4 +- .../androidx/media3/common/util/Util.java | 23 ++-- .../media3/common/util/BundleUtilTest.java | 42 ------- .../datasource/DefaultHttpDataSource.java | 2 +- .../datasource/cache/CachedContentIndex.java | 16 +-- .../media3/effect/EffectPlaybackTest.java | 3 - .../media3/exoplayer/AudioFocusManager.java | 6 +- .../analytics/MediaMetricsListener.java | 6 +- .../exoplayer/audio/AudioCapabilities.java | 3 +- .../exoplayer/audio/AudioTimestampPoller.java | 12 +- .../audio/AudioTrackPositionTracker.java | 10 +- .../drm/DefaultDrmSessionManager.java | 5 +- .../drm/DefaultDrmSessionManagerProvider.java | 2 +- .../media3/exoplayer/drm/DrmUtil.java | 6 +- .../exoplayer/mediacodec/MediaCodecInfo.java | 2 +- .../mediacodec/MediaCodecRenderer.java | 33 +----- .../exoplayer/mediacodec/MediaCodecUtil.java | 42 +------ .../video/VideoFrameReleaseHelper.java | 6 +- .../spherical/SphericalGLSurfaceView.java | 14 +-- .../media3/session/ConnectionState.java | 5 +- .../androidx/media3/session/PlayerInfo.java | 5 +- .../playback/gts/DashTestRunner.java | 25 ++-- .../playback/gts/EnumerateDecodersTest.java | 3 +- .../exoplayer/playback/gts/GtsTestUtil.java | 5 - .../session/common/HandlerThreadTestRule.java | 7 +- .../media3/session/MediaControllerTest.java | 10 +- ...ntrollerWithFrameworkMediaSessionTest.java | 6 +- ...aControllerWithMediaSessionCompatTest.java | 5 +- .../media3/session/MediaSessionTest.java | 6 +- .../session/MockMediaLibraryService.java | 6 +- .../session/MockMediaSessionService.java | 7 +- .../robolectric/ShadowMediaCodecConfig.java | 8 +- .../java/androidx/media3/ui/SubtitleView.java | 5 +- 42 files changed, 90 insertions(+), 424 deletions(-) delete mode 100644 libraries/common/src/main/java/androidx/media3/common/util/BundleUtil.java delete mode 100644 libraries/common/src/test/java/androidx/media3/common/util/BundleUtilTest.java diff --git a/demos/gl/src/main/java/androidx/media3/demo/gl/MainActivity.java b/demos/gl/src/main/java/androidx/media3/demo/gl/MainActivity.java index c9e7ccd11c..bd6ba4b1d8 100644 --- a/demos/gl/src/main/java/androidx/media3/demo/gl/MainActivity.java +++ b/demos/gl/src/main/java/androidx/media3/demo/gl/MainActivity.java @@ -143,7 +143,7 @@ public final class MainActivity extends Activity { ? Assertions.checkNotNull(intent.getData()) : Uri.parse(DEFAULT_MEDIA_URI); DrmSessionManager drmSessionManager; - if (Util.SDK_INT >= 18 && intent.hasExtra(DRM_SCHEME_EXTRA)) { + if (intent.hasExtra(DRM_SCHEME_EXTRA)) { String drmScheme = Assertions.checkNotNull(intent.getStringExtra(DRM_SCHEME_EXTRA)); String drmLicenseUrl = Assertions.checkNotNull(intent.getStringExtra(DRM_LICENSE_URL_EXTRA)); UUID drmSchemeUuid = Assertions.checkNotNull(Util.getDrmUuid(drmScheme)); diff --git a/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java b/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java index a82ebb006d..e57873ecdf 100644 --- a/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java +++ b/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java @@ -200,13 +200,6 @@ public class DownloadTracker { return; } - // The content is DRM protected. We need to acquire an offline license. - if (Util.SDK_INT < 18) { - Toast.makeText(context, R.string.error_drm_unsupported_before_api_18, Toast.LENGTH_LONG) - .show(); - Log.e(TAG, "Downloading DRM protected content is not supported on API versions below 18"); - return; - } // TODO(internal b/163107948): Support cases where DrmInitData are not in the manifest. if (!hasNonNullWidevineSchemaData(format.drmInitData)) { Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG) diff --git a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java b/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java index 155264fb8a..3c0da8d4dd 100644 --- a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java +++ b/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java @@ -361,11 +361,7 @@ public class PlayerActivity extends AppCompatActivity MediaItem.DrmConfiguration drmConfiguration = mediaItem.localConfiguration.drmConfiguration; if (drmConfiguration != null) { - if (Build.VERSION.SDK_INT < 18) { - showToast(R.string.error_drm_unsupported_before_api_18); - finish(); - return Collections.emptyList(); - } else if (!FrameworkMediaDrm.isCryptoSchemeSupported(drmConfiguration.scheme)) { + if (!FrameworkMediaDrm.isCryptoSchemeSupported(drmConfiguration.scheme)) { showToast(R.string.error_drm_unsupported_scheme); finish(); return Collections.emptyList(); diff --git a/demos/main/src/main/res/values/strings.xml b/demos/main/src/main/res/values/strings.xml index b8f6e7c320..b6097da61d 100644 --- a/demos/main/src/main/res/values/strings.xml +++ b/demos/main/src/main/res/values/strings.xml @@ -25,8 +25,6 @@ Playback failed - DRM content not supported on API levels below 18 - This device does not support the required DRM scheme This device does not provide a decoder for %1$s diff --git a/libraries/common/src/main/java/androidx/media3/common/Timeline.java b/libraries/common/src/main/java/androidx/media3/common/Timeline.java index 01146a68ed..70b5e2c2f0 100644 --- a/libraries/common/src/main/java/androidx/media3/common/Timeline.java +++ b/libraries/common/src/main/java/androidx/media3/common/Timeline.java @@ -29,7 +29,6 @@ import android.util.Pair; import androidx.annotation.Nullable; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.BundleCollectionUtil; -import androidx.media3.common.util.BundleUtil; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import com.google.common.base.Function; @@ -1453,8 +1452,8 @@ public abstract class Timeline implements Bundleable { } Bundle bundle = new Bundle(); - BundleUtil.putBinder(bundle, FIELD_WINDOWS, new BundleListRetriever(windowBundles)); - BundleUtil.putBinder(bundle, FIELD_PERIODS, new BundleListRetriever(periodBundles)); + bundle.putBinder(FIELD_WINDOWS, new BundleListRetriever(windowBundles)); + bundle.putBinder(FIELD_PERIODS, new BundleListRetriever(periodBundles)); bundle.putIntArray(FIELD_SHUFFLED_WINDOW_INDICES, shuffledWindowIndices); return bundle; } @@ -1503,9 +1502,9 @@ public abstract class Timeline implements Bundleable { @UnstableApi public static Timeline fromBundle(Bundle bundle) { ImmutableList windows = - fromBundleListRetriever(Window::fromBundle, BundleUtil.getBinder(bundle, FIELD_WINDOWS)); + fromBundleListRetriever(Window::fromBundle, bundle.getBinder(FIELD_WINDOWS)); ImmutableList periods = - fromBundleListRetriever(Period::fromBundle, BundleUtil.getBinder(bundle, FIELD_PERIODS)); + fromBundleListRetriever(Period::fromBundle, bundle.getBinder(FIELD_PERIODS)); @Nullable int[] shuffledWindowIndices = bundle.getIntArray(FIELD_SHUFFLED_WINDOW_INDICES); return new RemotableTimeline( windows, diff --git a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java index 5f272fa229..9727cab101 100644 --- a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java +++ b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java @@ -623,7 +623,7 @@ public class TrackSelectionParameters implements Bundleable { * Sets the preferred language and role flags for text tracks based on the accessibility * settings of {@link CaptioningManager}. * - *

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,9 +631,7 @@ public class TrackSelectionParameters implements Bundleable { @CanIgnoreReturnValue public Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings( Context context) { - if (Util.SDK_INT >= 19) { - setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(context); - } + setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(context); return this; } diff --git a/libraries/common/src/main/java/androidx/media3/common/util/BundleUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/BundleUtil.java deleted file mode 100644 index 16d9662011..0000000000 --- a/libraries/common/src/main/java/androidx/media3/common/util/BundleUtil.java +++ /dev/null @@ -1,112 +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 android.os.Bundle; -import android.os.IBinder; -import androidx.annotation.Nullable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** Utilities for {@link Bundle}. */ -@UnstableApi -public final class BundleUtil { - - private static final String TAG = "BundleUtil"; - - @Nullable private static Method getIBinderMethod; - @Nullable private static Method putIBinderMethod; - - /** - * Gets an {@link IBinder} inside a {@link Bundle} for all Android versions. - * - * @param bundle The bundle to get the {@link IBinder}. - * @param key The key to use while getting the {@link IBinder}. - * @return The {@link IBinder} that was obtained. - */ - @Nullable - public static IBinder getBinder(Bundle bundle, @Nullable String key) { - if (Util.SDK_INT >= 18) { - return bundle.getBinder(key); - } else { - return getBinderByReflection(bundle, key); - } - } - - /** - * Puts an {@link IBinder} inside a {@link Bundle} for all Android versions. - * - * @param bundle The bundle to insert the {@link IBinder}. - * @param key The key to use while putting the {@link IBinder}. - * @param binder The {@link IBinder} to put. - */ - public static void putBinder(Bundle bundle, @Nullable String key, @Nullable IBinder binder) { - if (Util.SDK_INT >= 18) { - bundle.putBinder(key, binder); - } else { - putBinderByReflection(bundle, key, binder); - } - } - - // Method.invoke may take null "key". - @SuppressWarnings("nullness:argument") - @Nullable - private static IBinder getBinderByReflection(Bundle bundle, @Nullable String key) { - @Nullable Method getIBinder = getIBinderMethod; - if (getIBinder == null) { - try { - getIBinderMethod = Bundle.class.getMethod("getIBinder", String.class); - getIBinderMethod.setAccessible(true); - } catch (NoSuchMethodException e) { - Log.i(TAG, "Failed to retrieve getIBinder method", e); - return null; - } - getIBinder = getIBinderMethod; - } - - try { - return (IBinder) getIBinder.invoke(bundle, key); - } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { - Log.i(TAG, "Failed to invoke getIBinder via reflection", e); - return null; - } - } - - // Method.invoke may take null "key" and "binder". - @SuppressWarnings("nullness:argument") - private static void putBinderByReflection( - Bundle bundle, @Nullable String key, @Nullable IBinder binder) { - @Nullable Method putIBinder = putIBinderMethod; - if (putIBinder == null) { - try { - putIBinderMethod = Bundle.class.getMethod("putIBinder", String.class, IBinder.class); - putIBinderMethod.setAccessible(true); - } catch (NoSuchMethodException e) { - Log.i(TAG, "Failed to retrieve putIBinder method", e); - return; - } - putIBinder = putIBinderMethod; - } - - try { - putIBinder.invoke(bundle, key, binder); - } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { - Log.i(TAG, "Failed to invoke putIBinder via reflection", e); - } - } - - private BundleUtil() {} -} diff --git a/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java b/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java index 9a885b2af2..9fb4dfc8d6 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java @@ -150,10 +150,7 @@ public final class EGLSurfaceTexture implements SurfaceTexture.OnFrameAvailableL if (context != null) { EGL14.eglDestroyContext(display, context); } - // EGL14.eglReleaseThread could crash before Android K (see [internal: b/11327779]). - if (Util.SDK_INT >= 19) { - EGL14.eglReleaseThread(); - } + EGL14.eglReleaseThread(); if (display != null && !display.equals(EGL14.EGL_NO_DISPLAY)) { // Android is unusual in that it uses a reference-counted EGLDisplay. So for // every eglInitialize() we need an eglTerminate(). diff --git a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java index c32b5edf05..d6f9113c52 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java @@ -192,7 +192,7 @@ public final class GlUtil { * EGLContext)}. */ public static boolean isSurfacelessContextExtensionSupported() { - return Util.SDK_INT >= 17 && Api17.isExtensionSupported(EXTENSION_SURFACELESS_CONTEXT); + return Api17.isExtensionSupported(EXTENSION_SURFACELESS_CONTEXT); } /** @@ -202,9 +202,6 @@ public final class GlUtil { * for HDR input. */ public static boolean isYuvTargetExtensionSupported() { - if (Util.SDK_INT < 17) { - return false; - } @Nullable String glExtensions; if (Util.areEqual(Api17.getCurrentContext(), EGL14.EGL_NO_CONTEXT)) { // Create a placeholder context and make it current to allow calling GLES20.glGetString(). @@ -226,7 +223,7 @@ public final class GlUtil { /** Returns whether {@link #EXTENSION_COLORSPACE_BT2020_PQ} is supported. */ public static boolean isBt2020PqExtensionSupported() { - return Util.SDK_INT >= 17 && Api17.isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ); + return Api17.isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ); } /** Returns an initialized default {@link EGLDisplay}. */ @@ -396,21 +393,16 @@ 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); - } + Api18.deleteSyncObject(syncObject); } /** 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. - } + try { + // glDeleteSync ignores a 0-valued sync object. + Api18.deleteSyncObject(syncObject); + } catch (GlException unused) { + // Suppress exceptions. } } @@ -614,7 +606,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); 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..f5510bd3eb 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 @@ -32,7 +32,7 @@ public final class TraceUtil { * Unicode code units long. */ public static void beginSection(String sectionName) { - if (MediaLibraryInfo.TRACE_ENABLED && Util.SDK_INT >= 18) { + if (MediaLibraryInfo.TRACE_ENABLED) { beginSectionV18(sectionName); } } @@ -43,7 +43,7 @@ public final class TraceUtil { * @see android.os.Trace#endSection() */ public static void endSection() { - if (MediaLibraryInfo.TRACE_ENABLED && Util.SDK_INT >= 18) { + if (MediaLibraryInfo.TRACE_ENABLED) { endSectionV18(); } } 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..a3e2f987c3 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 @@ -3134,15 +3134,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 +3211,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); + getDisplaySizeV17(display, displaySize); } return displaySize; } @@ -3708,10 +3703,6 @@ public final class Util { 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/analytics/MediaMetricsListener.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/analytics/MediaMetricsListener.java index c419d5d515..8f1122e2be 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/analytics/MediaMetricsListener.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/analytics/MediaMetricsListener.java @@ -754,10 +754,10 @@ public final class MediaMetricsListener return new ErrorInfo(errorCode, subErrorCode); } else if (Util.SDK_INT >= 23 && cause instanceof MediaDrmResetException) { return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_SYSTEM_ERROR, /* subErrorCode= */ 0); - } else if (Util.SDK_INT >= 18 && cause instanceof NotProvisionedException) { + } else if (cause instanceof NotProvisionedException) { return new ErrorInfo( PlaybackErrorEvent.ERROR_DRM_PROVISIONING_FAILED, /* subErrorCode= */ 0); - } else if (Util.SDK_INT >= 18 && cause instanceof DeniedByServerException) { + } else if (cause instanceof DeniedByServerException) { return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_DEVICE_REVOKED, /* subErrorCode= */ 0); } else if (cause instanceof UnsupportedDrmException) { return new ErrorInfo( @@ -810,7 +810,7 @@ public final class MediaMetricsListener } else if (cause instanceof AudioSink.WriteException) { int subErrorCode = ((AudioSink.WriteException) cause).errorCode; return new ErrorInfo(PlaybackErrorEvent.ERROR_AUDIO_TRACK_WRITE_FAILED, subErrorCode); - } else if (Util.SDK_INT >= 16 && cause instanceof MediaCodec.CryptoException) { + } else if (cause instanceof MediaCodec.CryptoException) { int subErrorCode = ((MediaCodec.CryptoException) cause).getErrorCode(); int errorCode = getDrmErrorCode(subErrorCode); return new ErrorInfo(errorCode, subErrorCode); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java index e9fba20498..0caca06d6e 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java @@ -354,8 +354,7 @@ public final class AudioCapabilities { } private static boolean deviceMaySetExternalSurroundSoundGlobalSetting() { - return Util.SDK_INT >= 17 - && ("Amazon".equals(Util.MANUFACTURER) || "Xiaomi".equals(Util.MANUFACTURER)); + return "Amazon".equals(Util.MANUFACTURER) || "Xiaomi".equals(Util.MANUFACTURER); } private static int getChannelConfigForPassthrough(int channelCount) { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java index 374fec488c..2e41e3b5d3 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java @@ -24,7 +24,6 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.media3.common.C; -import androidx.media3.common.util.Util; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -105,16 +104,11 @@ import java.lang.annotation.Target; /** * Creates a new audio timestamp poller. * - * @param audioTrack The audio track that will provide timestamps, if the platform supports it. + * @param audioTrack The audio track that will provide timestamps. */ public AudioTimestampPoller(AudioTrack audioTrack) { - if (Util.SDK_INT >= 19) { - audioTimestamp = new AudioTimestampV19(audioTrack); - reset(); - } else { - audioTimestamp = null; - updateState(STATE_NO_TIMESTAMP); - } + audioTimestamp = new AudioTimestampV19(audioTrack); + reset(); } /** diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTrackPositionTracker.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTrackPositionTracker.java index dffe32a0dc..3a8ca36465 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTrackPositionTracker.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTrackPositionTracker.java @@ -224,12 +224,10 @@ import java.lang.reflect.Method; */ public AudioTrackPositionTracker(Listener listener) { this.listener = checkNotNull(listener); - if (Util.SDK_INT >= 18) { - try { - getLatencyMethod = AudioTrack.class.getMethod("getLatency", (Class[]) null); - } catch (NoSuchMethodException e) { - // There's no guarantee this method exists. Do nothing. - } + try { + getLatencyMethod = AudioTrack.class.getMethod("getLatency", (Class[]) null); + } catch (NoSuchMethodException e) { + // There's no guarantee this method exists. Do nothing. } playheadOffsets = new long[MAX_PLAYHEAD_OFFSET_COUNT]; clock = Clock.DEFAULT; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java index f3db12b3df..bede9775e6 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java @@ -657,11 +657,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..666c0f298b 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 @@ -75,7 +75,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; } 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..f6def1cb5e 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 (Api18.isNotProvisionedException(exception)) { return PlaybackException.ERROR_CODE_DRM_PROVISIONING_FAILED; - } else if (Util.SDK_INT >= 18 && Api18.isDeniedByServerException(exception)) { + } else if (Api18.isDeniedByServerException(exception)) { 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 (Api18.isMissingSchemeDataException(exception)) { return PlaybackException.ERROR_CODE_DRM_CONTENT_ERROR; } else if (exception instanceof KeysExpiredException) { return PlaybackException.ERROR_CODE_DRM_LICENSE_EXPIRED; 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..956d934635 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,7 +695,7 @@ public final class MediaCodecInfo { } private static boolean isAdaptive(CodecCapabilities capabilities) { - return Util.SDK_INT >= 19 && isAdaptiveV19(capabilities); + return isAdaptiveV19(capabilities); } @RequiresApi(19) 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..ce036f2e2c 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 + return Util.SDK_INT == 19 && Util.MODEL.startsWith("SM-G800") - && ("OMX.Exynos.avc.dec".equals(name) || "OMX.Exynos.avc.dec.secure".equals(name))); + && ("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/video/VideoFrameReleaseHelper.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoFrameReleaseHelper.java index 6c1255c9fa..c042279ad9 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 @@ -172,7 +172,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 (Api17.isPlaceholderSurface(surface)) { // We don't care about dummy surfaces for release timing, since they're not visible. surface = null; } @@ -422,9 +422,7 @@ public final class VideoFrameReleaseHelper { @Nullable DisplayHelper displayHelper = null; if (context != null) { context = context.getApplicationContext(); - if (Util.SDK_INT >= 17) { - displayHelper = DisplayHelperV17.maybeBuildNewInstance(context); - } + displayHelper = DisplayHelperV17.maybeBuildNewInstance(context); if (displayHelper == null) { displayHelper = DisplayHelperV16.maybeBuildNewInstance(context); } 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..798d39782d 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,11 @@ 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..f6d8be6236 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 @@ -106,22 +106,19 @@ 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 { + // 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); } - return false; } public DashTestRunner(@Size(max = 23) String tag, HostActivity activity) { 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 396a423687..a85c8ce8f8 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 @@ -299,11 +299,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_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/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 From 963e517a5abf2c659d7849b922fc3e6af90b3580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Tue, 16 Jan 2024 11:29:08 +0100 Subject: [PATCH 02/12] Remove unnecessary `RequiresApi` annotation --- .../media3/demo/main/DownloadTracker.java | 2 -- .../media3/common/GlObjectsProvider.java | 4 ---- .../media3/common/TrackSelectionParameters.java | 2 -- .../media3/common/util/EGLSurfaceTexture.java | 2 -- .../java/androidx/media3/common/util/GlUtil.java | 16 ---------------- .../androidx/media3/common/util/TraceUtil.java | 15 ++------------- .../java/androidx/media3/common/util/Util.java | 3 --- .../androidx/media3/exoplayer/ExoPlayer.java | 1 - .../exoplayer/audio/AudioTimestampPoller.java | 2 -- .../media3/exoplayer/drm/DefaultDrmSession.java | 2 -- .../exoplayer/drm/DefaultDrmSessionManager.java | 2 -- .../drm/DefaultDrmSessionManagerProvider.java | 2 -- .../androidx/media3/exoplayer/drm/DrmUtil.java | 1 - .../media3/exoplayer/drm/DummyExoMediaDrm.java | 2 -- .../media3/exoplayer/drm/FrameworkMediaDrm.java | 1 - .../exoplayer/drm/OfflineLicenseHelper.java | 2 -- .../exoplayer/mediacodec/MediaCodecAdapter.java | 1 - .../mediacodec/MediaCodecBufferEnqueuer.java | 2 -- .../exoplayer/mediacodec/MediaCodecInfo.java | 1 - .../mediacodec/SynchronousMediaCodecAdapter.java | 1 - .../exoplayer/video/MediaCodecVideoRenderer.java | 1 - .../exoplayer/video/PlaceholderSurface.java | 2 -- .../exoplayer/video/VideoFrameReleaseHelper.java | 2 -- .../exoplayer/playback/gts/DashTestRunner.java | 2 -- .../media3/test/utils/AdditionalFailureInfo.java | 2 -- .../media3/test/utils/BitmapPixelTestUtil.java | 8 -------- .../test/utils/CapturingRenderersFactory.java | 2 -- .../test/utils/DataSourceContractTest.java | 2 -- .../media3/test/utils/HttpDataSourceTestEnv.java | 2 -- .../media3/test/utils/TextureBitmapReader.java | 4 ---- .../utils/VideoFrameProcessorTestRunner.java | 2 -- .../androidx/media3/ui/CaptionStyleCompat.java | 2 -- 32 files changed, 2 insertions(+), 93 deletions(-) diff --git a/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java b/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java index e57873ecdf..07d1b8deca 100644 --- a/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java +++ b/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java @@ -25,7 +25,6 @@ import android.os.Looper; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.annotation.OptIn; -import androidx.annotation.RequiresApi; import androidx.fragment.app.FragmentManager; import androidx.media3.common.C; import androidx.media3.common.DrmInitData; @@ -354,7 +353,6 @@ public class DownloadTracker { } /** Downloads a Widevine offline license in a background thread. */ - @RequiresApi(18) private static final class WidevineOfflineLicenseFetchTask { private final Format format; diff --git a/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java b/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java index e07d658a9e..72a4d049fe 100644 --- a/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java +++ b/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java @@ -21,7 +21,6 @@ import android.opengl.EGLContext; import android.opengl.EGLDisplay; import android.opengl.EGLSurface; import androidx.annotation.IntRange; -import androidx.annotation.RequiresApi; import androidx.media3.common.util.GlUtil.GlException; import androidx.media3.common.util.UnstableApi; @@ -39,7 +38,6 @@ public interface GlObjectsProvider { * @param configAttributes The attributes to configure EGL with. * @throws GlException If an error occurs during creation. */ - @RequiresApi(17) EGLContext createEglContext( EGLDisplay eglDisplay, @IntRange(from = 2, to = 3) int openGlVersion, int[] configAttributes) throws GlException; @@ -54,7 +52,6 @@ public interface GlObjectsProvider { * @param isEncoderInputSurface Whether the {@code surface} is the input surface of an encoder. * @throws GlException If an error occurs during creation. */ - @RequiresApi(17) EGLSurface createEglSurface( EGLDisplay eglDisplay, Object surface, @@ -72,7 +69,6 @@ public interface GlObjectsProvider { * surface. * @throws GlException If an error occurs during creation. */ - @RequiresApi(17) EGLSurface createFocusedPlaceholderEglSurface(EGLContext eglContext, EGLDisplay eglDisplay) throws GlException; diff --git a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java index 9727cab101..5339f64c61 100644 --- a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java +++ b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java @@ -28,7 +28,6 @@ import android.os.Looper; import android.view.accessibility.CaptioningManager; import androidx.annotation.IntDef; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.media3.common.util.BundleCollectionUtil; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; @@ -830,7 +829,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) { diff --git a/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java b/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java index 9fb4dfc8d6..c61505c332 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/EGLSurfaceTexture.java @@ -27,14 +27,12 @@ import android.opengl.GLES20; import android.os.Handler; import androidx.annotation.IntDef; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** Generates a {@link SurfaceTexture} using EGL/GLES functions. */ -@RequiresApi(17) @UnstableApi public final class EGLSurfaceTexture implements SurfaceTexture.OnFrameAvailableListener, Runnable { diff --git a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java index d6f9113c52..6f24da13c2 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java @@ -37,7 +37,6 @@ import android.opengl.Matrix; import androidx.annotation.DoNotInline; import androidx.annotation.IntRange; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.media3.common.C; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -227,7 +226,6 @@ public final class GlUtil { } /** Returns an initialized default {@link EGLDisplay}. */ - @RequiresApi(17) public static EGLDisplay getDefaultEglDisplay() throws GlException { return Api17.getDefaultEglDisplay(); } @@ -240,7 +238,6 @@ public final class GlUtil { * * @param eglDisplay The {@link EGLDisplay} to create an {@link EGLContext} for. */ - @RequiresApi(17) public static EGLContext createEglContext(EGLDisplay eglDisplay) throws GlException { return createEglContext( EGL14.EGL_NO_CONTEXT, eglDisplay, /* openGlVersion= */ 2, EGL_CONFIG_ATTRIBUTES_RGBA_8888); @@ -256,7 +253,6 @@ public final class GlUtil { * @param configAttributes The attributes to configure EGL with. Accepts either {@link * #EGL_CONFIG_ATTRIBUTES_RGBA_1010102}, or {@link #EGL_CONFIG_ATTRIBUTES_RGBA_8888}. */ - @RequiresApi(17) public static EGLContext createEglContext( EGLContext sharedContext, EGLDisplay eglDisplay, @@ -282,7 +278,6 @@ public final class GlUtil { * C#COLOR_TRANSFER_SDR}, {@link C#COLOR_TRANSFER_HLG} and {@link C#COLOR_TRANSFER_ST2084}. * @param isEncoderInputSurface Whether the {@code surface} is the input surface of an encoder. */ - @RequiresApi(17) public static EGLSurface createEglSurface( EGLDisplay eglDisplay, Object surface, @@ -325,7 +320,6 @@ public final class GlUtil { * @param configAttributes EGL configuration attributes. Valid arguments include {@link * #EGL_CONFIG_ATTRIBUTES_RGBA_8888} and {@link #EGL_CONFIG_ATTRIBUTES_RGBA_1010102}. */ - @RequiresApi(17) private static EGLSurface createPbufferSurface( EGLDisplay eglDisplay, int width, int height, int[] configAttributes) throws GlException { int[] pbufferAttributes = @@ -347,7 +341,6 @@ public final class GlUtil { * @param eglDisplay The {@link EGLDisplay} to attach the surface to. * @return {@link EGL14#EGL_NO_SURFACE} if supported and a 1x1 pixel buffer surface otherwise. */ - @RequiresApi(17) public static EGLSurface createFocusedPlaceholderEglSurface( EGLContext eglContext, EGLDisplay eglDisplay) throws GlException { // EGL_CONFIG_ATTRIBUTES_RGBA_1010102 could be used for HDR input, but EGL14.EGL_NO_SURFACE @@ -369,7 +362,6 @@ public final class GlUtil { *

Returns {@code 0} if no {@link EGLContext} {@linkplain #createFocusedPlaceholderEglSurface * is focused}. */ - @RequiresApi(17) public static long getContextMajorVersion() throws GlException { return Api17.getContextMajorVersion(); } @@ -381,7 +373,6 @@ 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; @@ -422,7 +413,6 @@ public final class GlUtil { } /** Gets the current {@link EGLContext context}. */ - @RequiresApi(17) public static EGLContext getCurrentContext() { return Api17.getCurrentContext(); } @@ -498,7 +488,6 @@ 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 { @@ -510,7 +499,6 @@ public final class GlUtil { * 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, @@ -712,7 +700,6 @@ 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); @@ -722,7 +709,6 @@ public final class GlUtil { * 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); @@ -751,7 +737,6 @@ public final class GlUtil { } } - @RequiresApi(17) private static final class Api17 { private Api17() {} @@ -921,7 +906,6 @@ public final class GlUtil { } } - @RequiresApi(18) private static final class Api18 { private Api18() {} 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 f5510bd3eb..418d110755 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,7 +15,6 @@ */ package androidx.media3.common.util; -import androidx.annotation.RequiresApi; import androidx.media3.common.MediaLibraryInfo; /** Calls through to {@link android.os.Trace} methods on supported API levels. */ @@ -33,7 +32,7 @@ public final class TraceUtil { */ public static void beginSection(String sectionName) { if (MediaLibraryInfo.TRACE_ENABLED) { - beginSectionV18(sectionName); + android.os.Trace.beginSection(sectionName); } } @@ -44,17 +43,7 @@ public final class TraceUtil { */ public static void endSection() { if (MediaLibraryInfo.TRACE_ENABLED) { - endSectionV18(); + android.os.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 a3e2f987c3..0d6a892ad5 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(); @@ -3698,7 +3696,6 @@ public final class Util { outSize.y = mode.getPhysicalHeight(); } - @RequiresApi(17) private static void getDisplaySizeV17(Display display, Point outSize) { display.getRealSize(outSize); } 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 videoEffects); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java index 2e41e3b5d3..d28d1add38 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java @@ -22,7 +22,6 @@ import android.media.AudioTimestamp; import android.media.AudioTrack; import androidx.annotation.IntDef; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.media3.common.C; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @@ -266,7 +265,6 @@ import java.lang.annotation.Target; } } - @RequiresApi(19) private static final class AudioTimestampV19 { private final AudioTrack audioTrack; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSession.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSession.java index 9699fedc2f..340ba92c75 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSession.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSession.java @@ -29,7 +29,6 @@ import android.os.SystemClock; import android.util.Pair; import androidx.annotation.GuardedBy; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.media3.common.C; import androidx.media3.common.DrmInitData.SchemeData; import androidx.media3.common.util.Assertions; @@ -57,7 +56,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.RequiresNonNull; /** A {@link DrmSession} that supports playbacks using {@link ExoMediaDrm}. */ -@RequiresApi(18) /* package */ class DefaultDrmSession implements DrmSession { /** Thrown when an unexpected exception or error is thrown during provisioning or key requests. */ diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java index bede9775e6..0376be83c9 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManager.java @@ -29,7 +29,6 @@ import android.os.Message; import android.os.SystemClock; import androidx.annotation.IntDef; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.media3.common.C; import androidx.media3.common.DrmInitData; import androidx.media3.common.DrmInitData.SchemeData; @@ -68,7 +67,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; *

This implementation supports pre-acquisition of sessions using {@link * #preacquireSession(DrmSessionEventListener.EventDispatcher, Format)}. */ -@RequiresApi(18) @UnstableApi public class DefaultDrmSessionManager implements DrmSessionManager { 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 666c0f298b..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; @@ -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 f6def1cb5e..ee2870c1aa 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 @@ -106,7 +106,6 @@ public final class DrmUtil { // Internal classes. - @RequiresApi(18) private static final class Api18 { @DoNotInline 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 956d934635..23031f3521 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 @@ -698,7 +698,6 @@ public final class MediaCodecInfo { return 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/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..4607b925df 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 @@ -1682,7 +1682,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..5a3e263597 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; @@ -37,7 +36,6 @@ import androidx.media3.common.util.Util; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** A placeholder {@link Surface}. */ -@RequiresApi(17) @UnstableApi public final class PlaceholderSurface extends Surface { 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 c042279ad9..b259334e0f 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 @@ -499,7 +499,6 @@ public final class VideoFrameReleaseHelper { } } - @RequiresApi(17) private static final class DisplayHelperV17 implements DisplayHelper, DisplayManager.DisplayListener { @@ -652,7 +651,6 @@ public final class VideoFrameReleaseHelper { } } - @RequiresApi(17) private static final class Api17 { @DoNotInline 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 f6d8be6236..b4061ae1a9 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; @@ -509,7 +508,6 @@ import java.util.List; * 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() { 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/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java b/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java index 3f1e8507aa..a24e22cdcd 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java @@ -114,7 +114,6 @@ 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) { @@ -149,7 +148,6 @@ public final class CaptionStyleCompat { this.typeface = typeface; } - @RequiresApi(19) @SuppressWarnings("ResourceType") private static CaptionStyleCompat createFromCaptionStyleV19( CaptioningManager.CaptionStyle captionStyle) { From 08ab18be778d43600351b1777802a19ecfa26fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Tue, 16 Jan 2024 11:30:32 +0100 Subject: [PATCH 03/12] Remove unnecessary `TargetApi` annotation --- .../androidx/media3/exoplayer/audio/AudioTimestampPoller.java | 4 ---- .../media3/exoplayer/video/MediaCodecVideoRenderer.java | 2 -- 2 files changed, 6 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java index d28d1add38..876e0ed988 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java @@ -17,7 +17,6 @@ package androidx.media3.exoplayer.audio; import static java.lang.annotation.ElementType.TYPE_USE; -import android.annotation.TargetApi; import android.media.AudioTimestamp; import android.media.AudioTrack; import androidx.annotation.IntDef; @@ -120,7 +119,6 @@ import java.lang.annotation.Target; * @param systemTimeUs The current system time, in microseconds. * @return Whether the timestamp was updated. */ - @TargetApi(19) // audioTimestamp will be null if Util.SDK_INT < 19. public boolean maybePollTimestamp(long systemTimeUs) { if (audioTimestamp == null || (systemTimeUs - lastTimestampSampleTimeUs) < sampleIntervalUs) { return false; @@ -226,7 +224,6 @@ import java.lang.annotation.Target; * If {@link #maybePollTimestamp(long)} or {@link #hasTimestamp()} returned {@code true}, returns * the system time at which the latest timestamp was sampled, in microseconds. */ - @TargetApi(19) // audioTimestamp will be null if Util.SDK_INT < 19. public long getTimestampSystemTimeUs() { return audioTimestamp != null ? audioTimestamp.getTimestampSystemTimeUs() : C.TIME_UNSET; } @@ -235,7 +232,6 @@ import java.lang.annotation.Target; * If {@link #maybePollTimestamp(long)} or {@link #hasTimestamp()} returned {@code true}, returns * the latest timestamp's position in frames. */ - @TargetApi(19) // audioTimestamp will be null if Util.SDK_INT < 19. public long getTimestampPositionFrames() { return audioTimestamp != null ? audioTimestamp.getTimestampPositionFrames() : C.INDEX_UNSET; } 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 4607b925df..6483a62e06 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 { @@ -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, From e1ba75c871138c31412bcb22d8d7d40b1271dbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Tue, 16 Jan 2024 11:34:08 +0100 Subject: [PATCH 04/12] Remove some API-dependant classes --- .../media3/exoplayer/drm/DrmUtil.java | 24 +++---------------- .../video/VideoFrameReleaseHelper.java | 10 +------- 2 files changed, 4 insertions(+), 30 deletions(-) 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 ee2870c1aa..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 (Api18.isNotProvisionedException(exception)) { + } else if (exception instanceof NotProvisionedException) { return PlaybackException.ERROR_CODE_DRM_PROVISIONING_FAILED; - } else if (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 (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,24 +106,6 @@ public final class DrmUtil { // Internal classes. - 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/video/VideoFrameReleaseHelper.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/VideoFrameReleaseHelper.java index b259334e0f..cf7df55bea 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 @@ -172,7 +172,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 (Api17.isPlaceholderSurface(surface)) { + if (surface instanceof PlaceholderSurface) { // We don't care about dummy surfaces for release timing, since they're not visible. surface = null; } @@ -650,12 +650,4 @@ public final class VideoFrameReleaseHelper { } } } - - private static final class Api17 { - - @DoNotInline - public static boolean isPlaceholderSurface(@Nullable Surface surface) { - return surface instanceof PlaceholderSurface; - } - } } From d327cb4795d916d373158b97cd4c1bfad51d7c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Tue, 16 Jan 2024 11:57:57 +0100 Subject: [PATCH 05/12] Code cleanup --- .../src/main/java/androidx/media3/common/util/Util.java | 6 +----- .../media3/exoplayer/mediacodec/MediaCodecInfo.java | 4 ---- 2 files changed, 1 insertion(+), 9 deletions(-) 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 0d6a892ad5..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 @@ -3210,7 +3210,7 @@ public final class Util { if (SDK_INT >= 23) { getDisplaySizeV23(display, displaySize); } else { - getDisplaySizeV17(display, displaySize); + display.getRealSize(displaySize); } return displaySize; } @@ -3696,10 +3696,6 @@ public final class Util { outSize.y = mode.getPhysicalHeight(); } - private static void getDisplaySizeV17(Display display, Point outSize) { - display.getRealSize(outSize); - } - private static String[] getSystemLocales() { Configuration config = Resources.getSystem().getConfiguration(); return SDK_INT >= 24 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 23031f3521..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,10 +695,6 @@ public final class MediaCodecInfo { } private static boolean isAdaptive(CodecCapabilities capabilities) { - return isAdaptiveV19(capabilities); - } - - private static boolean isAdaptiveV19(CodecCapabilities capabilities) { return capabilities.isFeatureSupported(CodecCapabilities.FEATURE_AdaptivePlayback); } From c0c1c315c5b7cdbc091f256988194f390b992810 Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Thu, 8 Feb 2024 18:04:04 +0000 Subject: [PATCH 06/12] In-line GlUtil.Api18 and VideoFrameReleaseHelper.DisplayHelperV16/17 Also put back a comment in DownloadTracker that is still relevant on API 19. Also deprecate PlaceholderSurface.newInstanceV17() in favour of just newInstance() --- .../media3/demo/main/DownloadTracker.java | 2 + .../androidx/media3/common/util/GlUtil.java | 355 +++++++----------- .../video/MediaCodecVideoRenderer.java | 4 +- .../exoplayer/video/PlaceholderSurface.java | 12 +- .../video/VideoFrameReleaseHelper.java | 94 +---- 5 files changed, 166 insertions(+), 301 deletions(-) diff --git a/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java b/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java index 07d1b8deca..8a530f87fb 100644 --- a/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java +++ b/demos/main/src/main/java/androidx/media3/demo/main/DownloadTracker.java @@ -199,6 +199,8 @@ public class DownloadTracker { return; } + // The content is DRM protected. We need to acquire an offline license. + // TODO(internal b/163107948): Support cases where DrmInitData are not in the manifest. if (!hasNonNullWidevineSchemaData(format.drmInitData)) { Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG) diff --git a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java index 6f24da13c2..d8d604c77d 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java @@ -180,7 +180,7 @@ public final class GlUtil { return false; } - return Api17.isExtensionSupported(EXTENSION_PROTECTED_CONTENT); + return isExtensionSupported(EXTENSION_PROTECTED_CONTENT); } /** @@ -191,7 +191,7 @@ public final class GlUtil { * EGLContext)}. */ public static boolean isSurfacelessContextExtensionSupported() { - return Api17.isExtensionSupported(EXTENSION_SURFACELESS_CONTEXT); + return isExtensionSupported(EXTENSION_SURFACELESS_CONTEXT); } /** @@ -202,7 +202,7 @@ public final class GlUtil { */ public static boolean isYuvTargetExtensionSupported() { @Nullable String glExtensions; - if (Util.areEqual(Api17.getCurrentContext(), EGL14.EGL_NO_CONTEXT)) { + if (Util.areEqual(EGL14.eglGetCurrentContext(), EGL14.EGL_NO_CONTEXT)) { // Create a placeholder context and make it current to allow calling GLES20.glGetString(). try { EGLDisplay eglDisplay = getDefaultEglDisplay(); @@ -222,12 +222,23 @@ public final class GlUtil { /** Returns whether {@link #EXTENSION_COLORSPACE_BT2020_PQ} is supported. */ public static boolean isBt2020PqExtensionSupported() { - return Api17.isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ); + return isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ); } /** Returns an initialized default {@link EGLDisplay}. */ public static EGLDisplay getDefaultEglDisplay() throws GlException { - return Api17.getDefaultEglDisplay(); + 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; } /** @@ -263,7 +274,23 @@ public final class GlUtil { Arrays.equals(configAttributes, EGL_CONFIG_ATTRIBUTES_RGBA_8888) || Arrays.equals(configAttributes, EGL_CONFIG_ATTRIBUTES_RGBA_1010102)); checkArgument(openGlVersion == 2 || openGlVersion == 3); - return Api17.createEglContext(sharedContext, eglDisplay, openGlVersion, configAttributes); + int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, openGlVersion, 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 " + + openGlVersion); + } + checkGlError(); + return eglContext; } /** @@ -308,7 +335,15 @@ public final class GlUtil { } else { throw new IllegalArgumentException("Unsupported color transfer: " + colorTransfer); } - return Api17.createEglSurface(eglDisplay, surface, configAttributes, windowAttributes); + EGLSurface eglSurface = + EGL14.eglCreateWindowSurface( + eglDisplay, + getEglConfig(eglDisplay, configAttributes), + surface, + windowAttributes, + /* offset= */ 0); + checkEglException("Error creating a new EGL surface"); + return eglSurface; } /** @@ -328,7 +363,14 @@ public final class GlUtil { EGL14.EGL_HEIGHT, height, EGL14.EGL_NONE }; - return Api17.createEglPbufferSurface(eglDisplay, configAttributes, pbufferAttributes); + EGLSurface eglSurface = + EGL14.eglCreatePbufferSurface( + eglDisplay, + getEglConfig(eglDisplay, configAttributes), + pbufferAttributes, + /* offset= */ 0); + checkEglException("Error creating a new EGL Pbuffer surface"); + return eglSurface; } /** @@ -363,8 +405,15 @@ public final class GlUtil { * is focused}. */ 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]; } /** * Returns a newly created sync object and inserts it into the GL command stream. @@ -374,8 +423,19 @@ public final class GlUtil { * less than 3.0. */ 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; + } } /** @@ -384,17 +444,12 @@ public final class GlUtil { *

The {@code syncObject} must not be used after deletion. */ public static void deleteSyncObject(long syncObject) throws GlException { - Api18.deleteSyncObject(syncObject); - } + deleteSyncObjectQuietly(syncObject); + checkGlError(); } /** Releases the GL sync object if set, suppressing any error. */ public static void deleteSyncObjectQuietly(long syncObject) { - try { - // glDeleteSync ignores a 0-valued sync object. - Api18.deleteSyncObject(syncObject); - } catch (GlException unused) { - // Suppress exceptions. - } + GLES30.glDeleteSync(syncObject); } /** @@ -407,14 +462,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}. */ public static EGLContext getCurrentContext() { - return Api17.getCurrentContext(); + return EGL14.eglGetCurrentContext(); } /** @@ -491,7 +546,7 @@ public final class GlUtil { public static void focusEglSurface( EGLDisplay eglDisplay, EGLContext eglContext, EGLSurface eglSurface, int width, int height) throws GlException { - Api17.focusRenderTarget( + focusRenderTarget( eglDisplay, eglContext, eglSurface, /* framebuffer= */ 0, width, height); } @@ -507,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); } /** @@ -702,7 +757,20 @@ public final class GlUtil { */ 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"); } /** @@ -711,7 +779,15 @@ public final class GlUtil { */ 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. */ @@ -737,201 +813,46 @@ public final class GlUtil { } } - 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]; } - 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/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java index 6483a62e06..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 @@ -803,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; } } @@ -890,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; } 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 5a3e263597..26e886342b 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 @@ -64,6 +64,14 @@ public final class PlaceholderSurface extends Surface { return secureMode != SECURE_MODE_NONE; } + /** + * @deprecated Use {@link #newInstance(Context, boolean)} instead. + */ + @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. @@ -76,12 +84,14 @@ 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); } + + private PlaceholderSurface( PlaceholderSurfaceThread thread, SurfaceTexture surfaceTexture, boolean secure) { super(surfaceTexture); 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 cf7df55bea..a8c90850f1 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 @@ -161,7 +161,7 @@ public final class VideoFrameReleaseHelper { resetAdjustment(); if (displayHelper != null) { checkNotNull(vsyncSampler).addObserver(); - displayHelper.register(this::updateDefaultDisplayRefreshRateParams); + displayHelper.register(); } updateSurfacePlaybackFrameRate(/* forceUpdate= */ false); } @@ -418,16 +418,11 @@ public final class VideoFrameReleaseHelper { } @Nullable - private static DisplayHelper maybeBuildDisplayHelper(@Nullable Context context) { - @Nullable DisplayHelper displayHelper = null; - if (context != null) { - context = context.getApplicationContext(); - displayHelper = DisplayHelperV17.maybeBuildNewInstance(context); - if (displayHelper == null) { - displayHelper = DisplayHelperV16.maybeBuildNewInstance(context); - } - } - return displayHelper; + private DisplayHelper maybeBuildDisplayHelper(@Nullable Context context) { + if (context == null) { return null;} + DisplayManager displayManager = + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + return displayManager != null ? new DisplayHelper(displayManager) : null; } // Nested classes. @@ -448,91 +443,28 @@ 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. - } - } - - 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()); } } From c4d9df970c350a6e32859388b8dcb11e95bdedc0 Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Thu, 8 Feb 2024 18:07:08 +0000 Subject: [PATCH 07/12] Format with google-java-format --- .../main/java/androidx/media3/common/util/GlUtil.java | 10 +++++----- .../exoplayer/mediacodec/MediaCodecRenderer.java | 4 ++-- .../exoplayer/video/VideoFrameReleaseHelper.java | 8 ++++---- .../video/spherical/SphericalGLSurfaceView.java | 3 ++- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java index d8d604c77d..e8985473eb 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java @@ -34,7 +34,6 @@ import android.opengl.GLES20; import android.opengl.GLES30; import android.opengl.GLUtils; import android.opengl.Matrix; -import androidx.annotation.DoNotInline; import androidx.annotation.IntRange; import androidx.annotation.Nullable; import androidx.media3.common.C; @@ -413,7 +412,8 @@ public final class GlUtil { currentEglContextVersion, /* offset= */ 0); checkGlError(); - return currentEglContextVersion[0]; } + return currentEglContextVersion[0]; + } /** * Returns a newly created sync object and inserts it into the GL command stream. @@ -445,7 +445,8 @@ public final class GlUtil { */ public static void deleteSyncObject(long syncObject) throws GlException { deleteSyncObjectQuietly(syncObject); - checkGlError(); } + checkGlError(); + } /** Releases the GL sync object if set, suppressing any error. */ public static void deleteSyncObjectQuietly(long syncObject) { @@ -546,8 +547,7 @@ public final class GlUtil { public static void focusEglSurface( EGLDisplay eglDisplay, EGLContext eglContext, EGLSurface eglSurface, int width, int height) throws GlException { - focusRenderTarget( - eglDisplay, eglContext, eglSurface, /* framebuffer= */ 0, width, height); + focusRenderTarget(eglDisplay, eglContext, eglSurface, /* framebuffer= */ 0, width, height); } /** 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 ce036f2e2c..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 @@ -2499,8 +2499,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer { */ private static boolean codecNeedsFlushWorkaround(String name) { return Util.SDK_INT == 19 - && Util.MODEL.startsWith("SM-G800") - && ("OMX.Exynos.avc.dec".equals(name) || "OMX.Exynos.avc.dec.secure".equals(name)); + && Util.MODEL.startsWith("SM-G800") + && ("OMX.Exynos.avc.dec".equals(name) || "OMX.Exynos.avc.dec.secure".equals(name)); } /** 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 a8c90850f1..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; @@ -419,7 +418,9 @@ public final class VideoFrameReleaseHelper { @Nullable private DisplayHelper maybeBuildDisplayHelper(@Nullable Context context) { - if (context == null) { return null;} + if (context == null) { + return null; + } DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); return displayManager != null ? new DisplayHelper(displayManager) : null; @@ -443,8 +444,7 @@ public final class VideoFrameReleaseHelper { } } - private final class DisplayHelper - implements DisplayManager.DisplayListener { + private final class DisplayHelper implements DisplayManager.DisplayListener { private final DisplayManager displayManager; 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 798d39782d..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 @@ -106,7 +106,8 @@ public final class SphericalGLSurfaceView extends GLSurfaceView { // 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); + @Nullable + Sensor orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR); if (orientationSensor == null) { orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); } From 205c8734cc3aed063f41b8acb81bb95f11b0a239 Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Thu, 8 Feb 2024 18:12:08 +0000 Subject: [PATCH 08/12] In-line more V19 methods in TrackSelectionParameters, AudioTimestampPoller and CaptionStyleCompat --- .../common/TrackSelectionParameters.java | 35 ++++++++----------- .../exoplayer/audio/AudioTimestampPoller.java | 1 + .../media3/ui/CaptionStyleCompat.java | 23 +++++------- 3 files changed, 24 insertions(+), 35 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java index 5339f64c61..d61b760ec3 100644 --- a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java +++ b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java @@ -630,7 +630,21 @@ public class TrackSelectionParameters implements Bundleable { @CanIgnoreReturnValue public Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings( Context context) { - 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; } @@ -829,25 +843,6 @@ public class TrackSelectionParameters implements Bundleable { return new TrackSelectionParameters(this); } - 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 normalizeLanguageCodes(String[] preferredTextLanguages) { ImmutableList.Builder listBuilder = ImmutableList.builder(); for (String language : checkNotNull(preferredTextLanguages)) { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java index 876e0ed988..aba711b7e8 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java @@ -261,6 +261,7 @@ import java.lang.annotation.Target; } } + // DO NOT SUBMIT in-line this private static final class AudioTimestampV19 { private final AudioTrack audioTrack; 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 a24e22cdcd..04ab0e6647 100644 --- a/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java +++ b/libraries/ui/src/main/java/androidx/media3/ui/CaptionStyleCompat.java @@ -114,14 +114,19 @@ public final class CaptionStyleCompat { * @param captionStyle A {@link CaptionStyle}. * @return The equivalent {@link CaptionStyleCompat}. */ + @SuppressWarnings("ResourceType") // DO NOT SUBMIT check this is still needed 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()); } } @@ -148,18 +153,6 @@ public final class CaptionStyleCompat { this.typeface = typeface; } - @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( From 1bf3101269394f865f13691f85488315f751ba4b Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Fri, 9 Feb 2024 15:04:49 +0000 Subject: [PATCH 09/12] Remove V19 from AudioTimestampPoller.AudioTimestampV19 --- .../media3/exoplayer/audio/AudioTimestampPoller.java | 9 ++++----- .../media3/exoplayer/video/PlaceholderSurface.java | 2 -- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java index aba711b7e8..cfc8982b57 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTimestampPoller.java @@ -91,7 +91,7 @@ import java.lang.annotation.Target; */ private static final int INITIALIZING_DURATION_US = 500_000; - @Nullable private final AudioTimestampV19 audioTimestamp; + @Nullable private final AudioTimestampWrapper audioTimestamp; private @State int state; private long initializeSystemTimeUs; @@ -105,7 +105,7 @@ import java.lang.annotation.Target; * @param audioTrack The audio track that will provide timestamps. */ public AudioTimestampPoller(AudioTrack audioTrack) { - audioTimestamp = new AudioTimestampV19(audioTrack); + audioTimestamp = new AudioTimestampWrapper(audioTrack); reset(); } @@ -261,8 +261,7 @@ import java.lang.annotation.Target; } } - // DO NOT SUBMIT in-line this - private static final class AudioTimestampV19 { + private static final class AudioTimestampWrapper { private final AudioTrack audioTrack; private final AudioTimestamp audioTimestamp; @@ -276,7 +275,7 @@ import java.lang.annotation.Target; * * @param audioTrack The audio track that will provide timestamps. */ - public AudioTimestampV19(AudioTrack audioTrack) { + public AudioTimestampWrapper(AudioTrack audioTrack) { this.audioTrack = audioTrack; audioTimestamp = new AudioTimestamp(); } 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 26e886342b..dc46bdd61f 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 @@ -90,8 +90,6 @@ public final class PlaceholderSurface extends Surface { return thread.init(secure ? secureMode : SECURE_MODE_NONE); } - - private PlaceholderSurface( PlaceholderSurfaceThread thread, SurfaceTexture surfaceTexture, boolean secure) { super(surfaceTexture); From e24febf1e2c48977e2422a4c880fffe62cdeb06e Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Tue, 13 Feb 2024 14:48:15 +0000 Subject: [PATCH 10/12] Small clean-ups and added @InlineMe annotation --- .../java/androidx/media3/common/util/TraceUtil.java | 11 ++++++----- .../media3/exoplayer/video/PlaceholderSurface.java | 4 ++++ .../java/androidx/media3/ui/CaptionStyleCompat.java | 1 - 3 files changed, 10 insertions(+), 6 deletions(-) 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 418d110755..d190ae4ee1 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,9 +15,10 @@ */ package androidx.media3.common.util; +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 { @@ -26,24 +27,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) { - android.os.Trace.beginSection(sectionName); + 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) { - android.os.Trace.endSection(); + Trace.endSection(); } } } 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 dc46bdd61f..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 @@ -33,6 +33,7 @@ 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}. */ @@ -67,6 +68,9 @@ public final class PlaceholderSurface extends Surface { /** * @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); 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 04ab0e6647..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,7 +114,6 @@ public final class CaptionStyleCompat { * @param captionStyle A {@link CaptionStyle}. * @return The equivalent {@link CaptionStyleCompat}. */ - @SuppressWarnings("ResourceType") // DO NOT SUBMIT check this is still needed public static CaptionStyleCompat createFromCaptionStyle( CaptioningManager.CaptionStyle captionStyle) { if (Util.SDK_INT >= 21) { From 868d2fedcbc72c0a83d04adee48b17c1507e6e34 Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Tue, 13 Feb 2024 15:11:24 +0000 Subject: [PATCH 11/12] Update api.txt --- api.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.txt b/api.txt index 884492e951..f61a17607b 100644 --- a/api.txt +++ b/api.txt @@ -1370,7 +1370,7 @@ package androidx.media3.exoplayer.analytics { package androidx.media3.exoplayer.drm { - @RequiresApi(18) public final class FrameworkMediaDrm { + public final class FrameworkMediaDrm { method public static boolean isCryptoSchemeSupported(java.util.UUID); } From b82f3410074cbecbfb915706b5000a8a1dfc68c8 Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Tue, 13 Feb 2024 17:11:03 +0000 Subject: [PATCH 12/12] In-line DashTestRunner.MediaDrmBuilder --- .../playback/gts/DashTestRunner.java | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) 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 b4061ae1a9..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 @@ -105,17 +105,15 @@ import java.util.List; @SuppressWarnings("ResourceType") public static boolean isL1WidevineAvailable(String mimeType) { - try { + 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; } - MediaDrm mediaDrm = MediaDrmBuilder.build(); String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY); - mediaDrm.release(); return WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty); - } catch (MediaCodecUtil.DecoderQueryException e) { + } catch (UnsupportedSchemeException | MediaCodecUtil.DecoderQueryException e) { throw new IllegalStateException(e); } } @@ -503,19 +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. - */ - private static final class MediaDrmBuilder { - - public static MediaDrm build() { - try { - return new MediaDrm(WIDEVINE_UUID); - } catch (UnsupportedSchemeException e) { - throw new IllegalStateException(e); - } - } - } }