From fcb263a40790e2a6413894d21f08b4041bb2f4dc Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Thu, 13 Aug 2020 09:31:43 +0100 Subject: [PATCH] Make DrmSessionManager take a Format instead of DrmInitData Skipping acquirePlaceholderSession which will be removed in a following change. PiperOrigin-RevId: 326402746 --- .../exoplayer2/demo/DownloadTracker.java | 21 +++++----- .../drm/DefaultDrmSessionManager.java | 24 +++++++----- .../exoplayer2/drm/DrmSessionManager.java | 39 ++++++++----------- .../exoplayer2/drm/OfflineLicenseHelper.java | 33 +++++++++------- .../source/ProgressiveMediaPeriod.java | 3 +- .../exoplayer2/source/SampleQueue.java | 6 +-- .../drm/DefaultDrmSessionManagerTest.java | 23 ++++++----- .../drm/OfflineLicenseHelperTest.java | 28 ++++++++----- .../source/dash/DashMediaPeriod.java | 4 +- .../exoplayer2/source/dash/DashUtil.java | 11 +++--- .../exoplayer2/source/dash/DashUtilTest.java | 16 ++++---- .../source/hls/HlsSampleStreamWrapper.java | 4 +- .../source/smoothstreaming/SsMediaPeriod.java | 5 +-- .../gts/DashWidevineOfflineTest.java | 6 +-- .../exoplayer2/testutil/FakeSampleStream.java | 2 +- 15 files changed, 115 insertions(+), 110 deletions(-) diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java index 268e28d5a7..8109263e55 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java @@ -191,8 +191,8 @@ public class DownloadTracker { @Override public void onPrepared(@NonNull DownloadHelper helper) { - @Nullable DrmInitData drmInitData = findDrmInitData(helper); - if (drmInitData != null) { + @Nullable Format format = getFirstFormatWithDrmInitData(helper); + if (format != null) { if (Util.SDK_INT < 18) { Toast.makeText(context, R.string.error_drm_unsupported_before_api_18, Toast.LENGTH_LONG) .show(); @@ -200,7 +200,7 @@ public class DownloadTracker { return; } // TODO(internal b/163107948): Support cases where DrmInitData are not in the manifest. - if (!hasSchemaData(drmInitData)) { + if (!hasSchemaData(format.drmInitData)) { Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG) .show(); Log.e( @@ -212,7 +212,7 @@ public class DownloadTracker { try { // TODO(internal b/163107948): Download the license on another thread to keep the UI // thread unblocked. - fetchOfflineLicense(drmInitData); + fetchOfflineLicense(format); } catch (DrmSession.DrmSessionException e) { Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG) .show(); @@ -308,14 +308,13 @@ public class DownloadTracker { } @RequiresApi(18) - private void fetchOfflineLicense(DrmInitData drmInitData) - throws DrmSession.DrmSessionException { + private void fetchOfflineLicense(Format format) throws DrmSession.DrmSessionException { OfflineLicenseHelper offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance( mediaItem.playbackProperties.drmConfiguration.licenseUri.toString(), httpDataSourceFactory, new DrmSessionEventListener.EventDispatcher()); - keySetId = offlineLicenseHelper.downloadLicense(drmInitData); + keySetId = offlineLicenseHelper.downloadLicense(format); } } @@ -333,11 +332,11 @@ public class DownloadTracker { } /** - * Returns the first non-null {@link DrmInitData} found in the content's tracks, or null if no - * {@link DrmInitData} are found. + * Returns the first {@link Format} with a non-null {@link Format#drmInitData} found in the + * content's tracks, or null if none is found. */ @Nullable - private DrmInitData findDrmInitData(DownloadHelper helper) { + private Format getFirstFormatWithDrmInitData(DownloadHelper helper) { for (int periodIndex = 0; periodIndex < helper.getPeriodCount(); periodIndex++) { MappedTrackInfo mappedTrackInfo = helper.getMappedTrackInfo(periodIndex); for (int rendererIndex = 0; @@ -349,7 +348,7 @@ public class DownloadTracker { for (int formatIndex = 0; formatIndex < trackGroup.length; formatIndex++) { Format format = trackGroup.getFormat(formatIndex); if (format.drmInitData != null) { - return format.drmInitData; + return format; } } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java index 5d1b526481..a593943e57 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java @@ -25,6 +25,7 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.ExoMediaDrm.OnEventListener; @@ -32,6 +33,7 @@ import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Log; +import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; @@ -223,8 +225,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager { } /** - * Signals that the {@link DrmInitData} passed to {@link #acquireSession} does not contain does - * not contain scheme data for the required UUID. + * Signals that the {@link Format#drmInitData} passed to {@link #acquireSession} does not contain + * scheme data for the required UUID. */ public static final class MissingSchemeDataException extends Exception { @@ -406,8 +408,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager { /** * Sets the mode, which determines the role of sessions acquired from the instance. This must be - * called before {@link #acquireSession(Looper, DrmSessionEventListener.EventDispatcher, - * DrmInitData)} or {@link #acquirePlaceholderSession} is called. + * called before {@link #acquireSession(Looper, DrmSessionEventListener.EventDispatcher, Format)} + * or {@link #acquirePlaceholderSession} is called. * *

By default, the mode is {@link #MODE_PLAYBACK} and a streaming license is requested when * required. @@ -498,13 +500,13 @@ public class DefaultDrmSessionManager implements DrmSessionManager { public DrmSession acquireSession( Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, - DrmInitData drmInitData) { + Format format) { initPlaybackLooper(playbackLooper); maybeCreateMediaDrmHandler(playbackLooper); @Nullable List schemeDatas = null; if (offlineLicenseKeySetId == null) { - schemeDatas = getSchemeDatas(drmInitData, uuid, false); + schemeDatas = getSchemeDatas(Assertions.checkNotNull(format.drmInitData), uuid, false); if (schemeDatas.isEmpty()) { final MissingSchemeDataException error = new MissingSchemeDataException(uuid); if (eventDispatcher != null) { @@ -546,16 +548,18 @@ public class DefaultDrmSessionManager implements DrmSessionManager { @Override @Nullable - public Class getExoMediaCryptoType( - @Nullable DrmInitData drmInitData, int trackType) { + public Class getExoMediaCryptoType(Format format) { Class exoMediaCryptoType = Assertions.checkNotNull(exoMediaDrm).getExoMediaCryptoType(); - if (drmInitData == null) { + if (format.drmInitData == null) { + int trackType = MimeTypes.getTrackType(format.sampleMimeType); return Util.linearSearch(useDrmSessionsForClearContentTrackTypes, trackType) != C.INDEX_UNSET ? exoMediaCryptoType : null; } else { - return canAcquireSession(drmInitData) ? exoMediaCryptoType : UnsupportedMediaCrypto.class; + return canAcquireSession(format.drmInitData) + ? exoMediaCryptoType + : UnsupportedMediaCrypto.class; } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionManager.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionManager.java index 2e618abac8..0f67481628 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmSessionManager.java @@ -18,7 +18,7 @@ package com.google.android.exoplayer2.drm; import android.os.Looper; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; +import com.google.android.exoplayer2.Format; /** Manages a DRM session. */ public interface DrmSessionManager { @@ -36,7 +36,7 @@ public interface DrmSessionManager { public DrmSession acquireSession( Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, - DrmInitData drmInitData) { + Format format) { return new ErrorStateDrmSession( new DrmSession.DrmSessionException( new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME))); @@ -44,9 +44,8 @@ public interface DrmSessionManager { @Override @Nullable - public Class getExoMediaCryptoType( - @Nullable DrmInitData drmInitData, int trackType) { - return drmInitData != null ? UnsupportedMediaCrypto.class : null; + public Class getExoMediaCryptoType(Format format) { + return format.drmInitData != null ? UnsupportedMediaCrypto.class : null; } }; @@ -86,41 +85,37 @@ public interface DrmSessionManager { } /** - * Returns a {@link DrmSession} for the specified {@link DrmInitData}, with an incremented - * reference count. When the caller no longer needs to use the instance, it must call {@link + * Returns a {@link DrmSession} for the specified {@link Format}, with an incremented reference + * count. When the caller no longer needs to use the instance, it must call {@link * DrmSession#release(DrmSessionEventListener.EventDispatcher)} to decrement the reference count. * * @param playbackLooper The looper associated with the media playback thread. * @param eventDispatcher The {@link DrmSessionEventListener.EventDispatcher} used to distribute * events, and passed on to {@link * DrmSession#acquire(DrmSessionEventListener.EventDispatcher)}. - * @param drmInitData DRM initialization data. All contained {@link SchemeData}s must contain - * non-null {@link SchemeData#data}. + * @param format The {@link Format} for which to acquire a {@link DrmSession}. Must contain a + * non-null {@link Format#drmInitData}. * @return The DRM session. */ DrmSession acquireSession( Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, - DrmInitData drmInitData); + Format format); /** - * Returns the {@link ExoMediaCrypto} type associated to sessions acquired using the given - * parameters. Returns the {@link UnsupportedMediaCrypto} type if this DRM session manager does - * not support the given {@link DrmInitData}. If {@code drmInitData} is null, returns an {@link - * ExoMediaCrypto} type if this DRM session manager would associate a {@link - * #acquirePlaceholderSession placeholder session} to the given {@code trackType}, or null - * otherwise. + * Returns the {@link ExoMediaCrypto} type associated to sessions acquired for the given {@link + * Format}. Returns the {@link UnsupportedMediaCrypto} type if this DRM session manager does not + * support "any of the DRM schemes defined in the given {@link Format}. If the {@link Format} + * describes unencrypted content, returns an {@link ExoMediaCrypto} type if this DRM session + * manager would associate a {@link #acquirePlaceholderSession placeholder session} to the given + * {@link Format}, or null otherwise. * - * @param drmInitData The {@link DrmInitData} to acquire sessions with. May be null for - * unencrypted content (See {@link #acquirePlaceholderSession placeholder sessions}). - * @param trackType The type of the track to which {@code drmInitData} belongs. Must be one of the - * {@link C}{@code .TRACK_TYPE_*} constants. + * @param format The {@link Format} for which to return the {@link ExoMediaCrypto} type. * @return The {@link ExoMediaCrypto} type associated to sessions acquired using the given * parameters, or the {@link UnsupportedMediaCrypto} type if the provided {@code drmInitData} * is not supported, or {@code null} if {@code drmInitData} is null and no DRM session will be * associated to the given {@code trackType}. */ @Nullable - Class getExoMediaCryptoType( - @Nullable DrmInitData drmInitData, int trackType); + Class getExoMediaCryptoType(Format format); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java index 7c659b0a27..71091c878d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/OfflineLicenseHelper.java @@ -22,6 +22,7 @@ import android.os.HandlerThread; import android.util.Pair; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; @@ -34,7 +35,8 @@ import java.util.UUID; @RequiresApi(18) public final class OfflineLicenseHelper { - private static final DrmInitData EMPTY_DRM_INIT_DATA = new DrmInitData(); + private static final Format FORMAT_WITH_EMPTY_DRM_INIT_DATA = + new Format.Builder().setDrmInitData(new DrmInitData()).build(); private final ConditionVariable conditionVariable; private final DefaultDrmSessionManager drmSessionManager; @@ -182,13 +184,13 @@ public final class OfflineLicenseHelper { /** * Downloads an offline license. * - * @param drmInitData The {@link DrmInitData} for the content whose license is to be downloaded. + * @param format The {@link Format} of the content whose license is to be downloaded. * @return The key set id for the downloaded license. * @throws DrmSessionException Thrown when a DRM session error occurs. */ - public synchronized byte[] downloadLicense(DrmInitData drmInitData) throws DrmSessionException { - Assertions.checkArgument(drmInitData != null); - return blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, drmInitData); + public synchronized byte[] downloadLicense(Format format) throws DrmSessionException { + Assertions.checkArgument(format.drmInitData != null); + return blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, format); } /** @@ -202,7 +204,9 @@ public final class OfflineLicenseHelper { throws DrmSessionException { Assertions.checkNotNull(offlineLicenseKeySetId); return blockingKeyRequest( - DefaultDrmSessionManager.MODE_DOWNLOAD, offlineLicenseKeySetId, EMPTY_DRM_INIT_DATA); + DefaultDrmSessionManager.MODE_DOWNLOAD, + offlineLicenseKeySetId, + FORMAT_WITH_EMPTY_DRM_INIT_DATA); } /** @@ -215,7 +219,9 @@ public final class OfflineLicenseHelper { throws DrmSessionException { Assertions.checkNotNull(offlineLicenseKeySetId); blockingKeyRequest( - DefaultDrmSessionManager.MODE_RELEASE, offlineLicenseKeySetId, EMPTY_DRM_INIT_DATA); + DefaultDrmSessionManager.MODE_RELEASE, + offlineLicenseKeySetId, + FORMAT_WITH_EMPTY_DRM_INIT_DATA); } /** @@ -231,7 +237,9 @@ public final class OfflineLicenseHelper { drmSessionManager.prepare(); DrmSession drmSession = openBlockingKeyRequest( - DefaultDrmSessionManager.MODE_QUERY, offlineLicenseKeySetId, EMPTY_DRM_INIT_DATA); + DefaultDrmSessionManager.MODE_QUERY, + offlineLicenseKeySetId, + FORMAT_WITH_EMPTY_DRM_INIT_DATA); DrmSessionException error = drmSession.getError(); Pair licenseDurationRemainingSec = WidevineUtil.getLicenseDurationRemainingSec(drmSession); @@ -254,11 +262,10 @@ public final class OfflineLicenseHelper { } private byte[] blockingKeyRequest( - @Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData) + @Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format) throws DrmSessionException { drmSessionManager.prepare(); - DrmSession drmSession = - openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, drmInitData); + DrmSession drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, format); DrmSessionException error = drmSession.getError(); byte[] keySetId = drmSession.getOfflineLicenseKeySetId(); drmSession.release(eventDispatcher); @@ -270,11 +277,11 @@ public final class OfflineLicenseHelper { } private DrmSession openBlockingKeyRequest( - @Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, DrmInitData drmInitData) { + @Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format) { drmSessionManager.setMode(licenseMode, offlineLicenseKeySetId); conditionVariable.close(); DrmSession drmSession = - drmSessionManager.acquireSession(handlerThread.getLooper(), eventDispatcher, drmInitData); + drmSessionManager.acquireSession(handlerThread.getLooper(), eventDispatcher, format); // Block current thread until key loading is finished conditionVariable.block(); return drmSession; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java index 3c0c35307b..121eeb940d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java @@ -782,8 +782,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } trackFormat = trackFormat.copyWithExoMediaCryptoType( - drmSessionManager.getExoMediaCryptoType( - trackFormat.drmInitData, MimeTypes.getTrackType(trackFormat.sampleMimeType))); + drmSessionManager.getExoMediaCryptoType(trackFormat)); trackArray[i] = new TrackGroup(trackFormat); } trackState = new TrackState(new TrackGroupArray(trackArray), trackIsAudioVideoFlags); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java index 42b9187ad0..515f805845 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java @@ -832,9 +832,7 @@ public class SampleQueue implements TrackOutput { @Nullable DrmInitData newDrmInitData = newFormat.drmInitData; outputFormatHolder.format = - newFormat.copyWithExoMediaCryptoType( - drmSessionManager.getExoMediaCryptoType( - newFormat.drmInitData, MimeTypes.getTrackType(newFormat.sampleMimeType))); + newFormat.copyWithExoMediaCryptoType(drmSessionManager.getExoMediaCryptoType(newFormat)); outputFormatHolder.drmSession = currentDrmSession; if (!isFirstFormat && Util.areEqual(oldDrmInitData, newDrmInitData)) { // Nothing to do. @@ -845,7 +843,7 @@ public class SampleQueue implements TrackOutput { @Nullable DrmSession previousSession = currentDrmSession; currentDrmSession = newDrmInitData != null - ? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newDrmInitData) + ? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat) : drmSessionManager.acquirePlaceholderSession( playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType)); outputFormatHolder.drmSession = currentDrmSession; diff --git a/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java index 3c203f1457..a700350b0b 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManagerTest.java @@ -21,6 +21,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import android.os.Looper; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.testutil.FakeExoMediaDrm; import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.util.Assertions; @@ -46,7 +47,8 @@ public class DefaultDrmSessionManagerTest { ImmutableList.of( new DrmInitData.SchemeData( DRM_SCHEME_UUID, MimeTypes.VIDEO_MP4, /* data= */ TestUtil.createByteArray(1, 2, 3))); - private static final DrmInitData DRM_INIT_DATA = new DrmInitData(DRM_SCHEME_DATAS); + private static final Format FORMAT_WITH_DRM_INIT_DATA = + new Format.Builder().setDrmInitData(new DrmInitData(DRM_SCHEME_DATAS)).build(); @Test(timeout = 10_000) public void acquireSession_triggersKeyLoadAndSessionIsOpened() throws Exception { @@ -62,7 +64,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - DRM_INIT_DATA); + FORMAT_WITH_DRM_INIT_DATA); waitForOpenedWithKeys(drmSession); assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS); @@ -85,7 +87,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - DRM_INIT_DATA); + FORMAT_WITH_DRM_INIT_DATA); waitForOpenedWithKeys(drmSession); assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS); @@ -110,7 +112,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - DRM_INIT_DATA); + FORMAT_WITH_DRM_INIT_DATA); waitForOpenedWithKeys(drmSession); drmSession.release(/* eventDispatcher= */ null); @@ -132,7 +134,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - DRM_INIT_DATA); + FORMAT_WITH_DRM_INIT_DATA); waitForOpenedWithKeys(drmSession); drmSession.release(/* eventDispatcher= */ null); @@ -147,7 +149,8 @@ public class DefaultDrmSessionManagerTest { ImmutableList.of(DRM_SCHEME_DATAS.get(0).copyWithData(TestUtil.createByteArray(4, 5, 6))); FakeExoMediaDrm.LicenseServer licenseServer = FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS, secondSchemeDatas); - DrmInitData secondInitData = new DrmInitData(secondSchemeDatas); + Format secondFormatWithDrmInitData = + new Format.Builder().setDrmInitData(new DrmInitData(secondSchemeDatas)).build(); DrmSessionManager drmSessionManager = new DefaultDrmSessionManager.Builder() .setUuidAndExoMediaDrmProvider( @@ -161,7 +164,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - DRM_INIT_DATA); + FORMAT_WITH_DRM_INIT_DATA); waitForOpenedWithKeys(firstDrmSession); firstDrmSession.release(/* eventDispatcher= */ null); @@ -172,7 +175,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - secondInitData); + secondFormatWithDrmInitData); // The drmSessionManager had to release firstDrmSession in order to acquire secondDrmSession. assertThat(firstDrmSession.getState()).isEqualTo(DrmSession.STATE_RELEASED); @@ -195,7 +198,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - DRM_INIT_DATA); + FORMAT_WITH_DRM_INIT_DATA); waitForOpenedWithKeys(firstDrmSession); firstDrmSession.release(/* eventDispatcher= */ null); @@ -207,7 +210,7 @@ public class DefaultDrmSessionManagerTest { drmSessionManager.acquireSession( /* playbackLooper= */ Assertions.checkNotNull(Looper.myLooper()), /* eventDispatcher= */ null, - DRM_INIT_DATA); + FORMAT_WITH_DRM_INIT_DATA); assertThat(secondDrmSession).isSameInstanceAs(firstDrmSession); // Let the timeout definitely expire, and check the session didn't get released. diff --git a/library/core/src/test/java/com/google/android/exoplayer2/drm/OfflineLicenseHelperTest.java b/library/core/src/test/java/com/google/android/exoplayer2/drm/OfflineLicenseHelperTest.java index 115bf4cabe..ae579b1b7c 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/drm/OfflineLicenseHelperTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/drm/OfflineLicenseHelperTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; import android.util.Pair; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; import java.util.HashMap; import org.junit.After; @@ -70,7 +71,8 @@ public class OfflineLicenseHelperTest { byte[] keySetId = {2, 5, 8}; setStubKeySetId(keySetId); - byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); + byte[] offlineLicenseKeySetId = + offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData()); assertOfflineLicenseKeySetIdEqual(keySetId, offlineLicenseKeySetId); @@ -85,9 +87,9 @@ public class OfflineLicenseHelperTest { } @Test - public void downloadLicenseFailsIfNullInitData() throws Exception { + public void downloadLicenseFailsIfNullDrmInitData() throws Exception { try { - offlineLicenseHelper.downloadLicense(null); + offlineLicenseHelper.downloadLicense(new Format.Builder().build()); fail(); } catch (IllegalArgumentException e) { // Expected. @@ -99,7 +101,7 @@ public class OfflineLicenseHelperTest { setStubLicenseAndPlaybackDurationValues(1000, 200); try { - offlineLicenseHelper.downloadLicense(newDrmInitData()); + offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData()); fail(); } catch (Exception e) { // Expected. @@ -110,7 +112,8 @@ public class OfflineLicenseHelperTest { public void downloadLicenseDoesNotFailIfDurationNotAvailable() throws Exception { setDefaultStubKeySetId(); - byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); + byte[] offlineLicenseKeySetId = + offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData()); assertThat(offlineLicenseKeySetId).isNotNull(); } @@ -122,7 +125,8 @@ public class OfflineLicenseHelperTest { setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration); setDefaultStubKeySetId(); - byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); + byte[] offlineLicenseKeySetId = + offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData()); Pair licenseDurationRemainingSec = offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId); @@ -138,7 +142,8 @@ public class OfflineLicenseHelperTest { setStubLicenseAndPlaybackDurationValues(licenseDuration, playbackDuration); setDefaultStubKeySetId(); - byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData()); + byte[] offlineLicenseKeySetId = + offlineLicenseHelper.downloadLicense(newFormatWithDrmInitData()); Pair licenseDurationRemainingSec = offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId); @@ -173,8 +178,11 @@ public class OfflineLicenseHelperTest { when(mediaDrm.queryKeyStatus(any(byte[].class))).thenReturn(keyStatus); } - private static DrmInitData newDrmInitData() { - return new DrmInitData( - new SchemeData(C.WIDEVINE_UUID, "mimeType", new byte[] {1, 4, 7, 0, 3, 6})); + private static Format newFormatWithDrmInitData() { + return new Format.Builder() + .setDrmInitData( + new DrmInitData( + new SchemeData(C.WIDEVINE_UUID, "mimeType", new byte[] {1, 4, 7, 0, 3, 6}))) + .build(); } } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java index c67c424284..81d72b61f3 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java @@ -665,9 +665,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; for (int j = 0; j < formats.length; j++) { Format format = representations.get(j).format; formats[j] = - format.copyWithExoMediaCryptoType( - drmSessionManager.getExoMediaCryptoType( - format.drmInitData, MimeTypes.getTrackType(format.sampleMimeType))); + format.copyWithExoMediaCryptoType(drmSessionManager.getExoMediaCryptoType(format)); } AdaptationSet firstAdaptationSet = adaptationSets.get(adaptationSetIndices[0]); diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java index b0c892de03..5dc6662d4f 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashUtil.java @@ -19,7 +19,6 @@ import android.net.Uri; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.extractor.ChunkIndex; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; @@ -75,15 +74,15 @@ public final class DashUtil { } /** - * Loads {@link DrmInitData} for a given period in a DASH manifest. + * Loads a {@link Format} for acquiring keys for a given period in a DASH manifest. * * @param dataSource The {@link HttpDataSource} from which data should be loaded. * @param period The {@link Period}. - * @return The loaded {@link DrmInitData}, or null if none is defined. + * @return The loaded {@link Format}, or null if none is defined. * @throws IOException Thrown when there is an error while loading. */ @Nullable - public static DrmInitData loadDrmInitData(DataSource dataSource, Period period) + public static Format loadFormatWithDrmInitData(DataSource dataSource, Period period) throws IOException { int primaryTrackType = C.TRACK_TYPE_VIDEO; Representation representation = getFirstRepresentation(period, primaryTrackType); @@ -97,8 +96,8 @@ public final class DashUtil { Format manifestFormat = representation.format; Format sampleFormat = DashUtil.loadSampleFormat(dataSource, primaryTrackType, representation); return sampleFormat == null - ? manifestFormat.drmInitData - : sampleFormat.withManifestFormatInfo(manifestFormat).drmInitData; + ? manifestFormat + : sampleFormat.withManifestFormatInfo(manifestFormat); } /** diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java index 3176b06865..188d1b2a18 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DashUtilTest.java @@ -40,29 +40,29 @@ public final class DashUtilTest { @Test public void loadDrmInitDataFromManifest() throws Exception { Period period = newPeriod(newAdaptationSet(newRepresentation(newDrmInitData()))); - DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period); - assertThat(drmInitData).isEqualTo(newDrmInitData()); + Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period); + assertThat(format.drmInitData).isEqualTo(newDrmInitData()); } @Test public void loadDrmInitDataMissing() throws Exception { Period period = newPeriod(newAdaptationSet(newRepresentation(null /* no init data */))); - DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period); - assertThat(drmInitData).isNull(); + Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period); + assertThat(format.drmInitData).isNull(); } @Test public void loadDrmInitDataNoRepresentations() throws Exception { Period period = newPeriod(newAdaptationSet(/* no representation */ )); - DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period); - assertThat(drmInitData).isNull(); + Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period); + assertThat(format).isNull(); } @Test public void loadDrmInitDataNoAdaptationSets() throws Exception { Period period = newPeriod(/* no adaptation set */ ); - DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period); - assertThat(drmInitData).isNull(); + Format format = DashUtil.loadFormatWithDrmInitData(DummyDataSource.INSTANCE, period); + assertThat(format).isNull(); } private static Period newPeriod(AdaptationSet... adaptationSets) { diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 0040724ee3..89e7687a21 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -1319,9 +1319,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; for (int j = 0; j < trackGroup.length; j++) { Format format = trackGroup.getFormat(j); exposedFormats[j] = - format.copyWithExoMediaCryptoType( - drmSessionManager.getExoMediaCryptoType( - format.drmInitData, MimeTypes.getTrackType(format.sampleMimeType))); + format.copyWithExoMediaCryptoType(drmSessionManager.getExoMediaCryptoType(format)); } trackGroups[i] = new TrackGroup(exposedFormats); } diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java index f92d67e3b8..b6e21cd870 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java @@ -36,7 +36,6 @@ import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.TransferListener; -import com.google.android.exoplayer2.util.MimeTypes; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -267,9 +266,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; Format manifestFormat = manifestFormats[j]; exposedFormats[j] = manifestFormat.copyWithExoMediaCryptoType( - drmSessionManager.getExoMediaCryptoType( - manifestFormat.drmInitData, - MimeTypes.getTrackType(manifestFormat.sampleMimeType))); + drmSessionManager.getExoMediaCryptoType(manifestFormat)); } trackGroups[i] = new TrackGroup(exposedFormats); } diff --git a/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashWidevineOfflineTest.java b/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashWidevineOfflineTest.java index bc0fc6a95e..23b5cc7f17 100644 --- a/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashWidevineOfflineTest.java +++ b/playbacktests/src/androidTest/java/com/google/android/exoplayer2/playbacktests/gts/DashWidevineOfflineTest.java @@ -24,8 +24,8 @@ import android.net.Uri; import android.util.Pair; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.rule.ActivityTestRule; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Player; -import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.DrmSessionEventListener; import com.google.android.exoplayer2.drm.OfflineLicenseHelper; @@ -213,8 +213,8 @@ public final class DashWidevineOfflineTest { DataSource dataSource = httpDataSourceFactory.createDataSource(); DashManifest dashManifest = DashUtil.loadManifest(dataSource, Uri.parse(DashTestData.WIDEVINE_H264_MANIFEST)); - DrmInitData drmInitData = DashUtil.loadDrmInitData(dataSource, dashManifest.getPeriod(0)); - offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(drmInitData); + Format format = DashUtil.loadFormatWithDrmInitData(dataSource, dashManifest.getPeriod(0)); + offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(format); assertThat(offlineLicenseKeySetId).isNotNull(); assertThat(offlineLicenseKeySetId.length).isGreaterThan(0); testRunner.setOfflineLicenseKeySetId(offlineLicenseKeySetId); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java index 85bccf96e5..824d3c02e3 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeSampleStream.java @@ -275,7 +275,7 @@ public class FakeSampleStream implements SampleStream { Looper playbackLooper = Assertions.checkNotNull(Looper.myLooper()); currentDrmSession = newDrmInitData != null - ? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newDrmInitData) + ? drmSessionManager.acquireSession(playbackLooper, drmEventDispatcher, newFormat) : drmSessionManager.acquirePlaceholderSession( playbackLooper, MimeTypes.getTrackType(newFormat.sampleMimeType)); outputFormatHolder.drmSession = currentDrmSession;