Search in sources :

Example 1 with DrmSession

use of androidx.media3.exoplayer.drm.DrmSession in project media by androidx.

the class MediaCodecRenderer method drmNeedsCodecReinitialization.

/**
 * Returns whether it's necessary to re-initialize the codec to handle a DRM change. If {@code
 * false} is returned then either {@code oldSession == newSession} (i.e., there was no change), or
 * it's possible to update the existing codec using MediaCrypto.setMediaDrmSession.
 */
private boolean drmNeedsCodecReinitialization(MediaCodecInfo codecInfo, Format newFormat, @Nullable DrmSession oldSession, @Nullable DrmSession newSession) throws ExoPlaybackException {
    if (oldSession == newSession) {
        // No need to re-initialize if the old and new sessions are the same.
        return false;
    }
    if (newSession == null || oldSession == null) {
        // Changing from DRM to no DRM and vice-versa always requires re-initialization.
        return true;
    }
    if (Util.SDK_INT < 23) {
        // required to switch to newSession on older API levels.
        return true;
    }
    if (C.PLAYREADY_UUID.equals(oldSession.getSchemeUuid()) || C.PLAYREADY_UUID.equals(newSession.getSchemeUuid())) {
        // TODO: Add an API check once [Internal ref: b/128835874] is fixed.
        return true;
    }
    @Nullable FrameworkCryptoConfig newCryptoConfig = getFrameworkCryptoConfig(newSession);
    if (newCryptoConfig == null) {
        // the case is to occur, so we re-initialize in this case.
        return true;
    }
    boolean requiresSecureDecoder;
    if (newCryptoConfig.forceAllowInsecureDecoderComponents) {
        requiresSecureDecoder = false;
    } else {
        requiresSecureDecoder = newSession.requiresSecureDecoder(newFormat.sampleMimeType);
    }
    if (!codecInfo.secure && requiresSecureDecoder) {
        // output path.
        return true;
    }
    return false;
}
Also used : FrameworkCryptoConfig(androidx.media3.exoplayer.drm.FrameworkCryptoConfig) Nullable(androidx.annotation.Nullable)

Example 2 with DrmSession

use of androidx.media3.exoplayer.drm.DrmSession in project media by androidx.

the class OfflineLicenseHelper method blockingKeyRequest.

private byte[] blockingKeyRequest(@Mode int licenseMode, @Nullable byte[] offlineLicenseKeySetId, Format format) throws DrmSessionException {
    drmSessionManager.setPlayer(handlerThread.getLooper(), PlayerId.UNSET);
    drmSessionManager.prepare();
    DrmSession drmSession = openBlockingKeyRequest(licenseMode, offlineLicenseKeySetId, format);
    DrmSessionException error = drmSession.getError();
    byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
    drmSession.release(eventDispatcher);
    drmSessionManager.release();
    if (error != null) {
        throw error;
    }
    return Assertions.checkNotNull(keySetId);
}
Also used : DrmSessionException(androidx.media3.exoplayer.drm.DrmSession.DrmSessionException)

Example 3 with DrmSession

use of androidx.media3.exoplayer.drm.DrmSession in project media by androidx.

the class DefaultAnalyticsCollectorTest method drmEvents_periodsWithSameDrmData_keysReusedButLoadEventReportedTwice.

@Test
public void drmEvents_periodsWithSameDrmData_keysReusedButLoadEventReportedTwice() throws Exception {
    BlockingDrmCallback mediaDrmCallback = BlockingDrmCallback.returnsEmpty();
    DrmSessionManager blockingDrmSessionManager = new DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm.Builder().setEnforceValidKeyResponses(false).build()).setMultiSession(true).build(mediaDrmCallback);
    MediaSource mediaSource = new ConcatenatingMediaSource(new FakeMediaSource(SINGLE_PERIOD_TIMELINE, blockingDrmSessionManager, VIDEO_FORMAT_DRM_1), new FakeMediaSource(SINGLE_PERIOD_TIMELINE, blockingDrmSessionManager, VIDEO_FORMAT_DRM_1));
    TestAnalyticsListener listener = runAnalyticsTest(mediaSource, // already preacquired by the time the key load completes).
    new ActionSchedule.Builder(TAG).waitForIsLoading(false).waitForIsLoading(true).waitForIsLoading(false).executeRunnable(mediaDrmCallback.keyCondition::open).build());
    populateEventIds(listener.lastReportedTimeline);
    assertThat(listener.getEvents(EVENT_DRM_SESSION_MANAGER_ERROR)).isEmpty();
    assertThat(listener.getEvents(EVENT_DRM_SESSION_ACQUIRED)).containsExactly(period0, period1).inOrder();
    // This includes both period0 and period1 because period1's DrmSession was preacquired before
    // the key load completed. There's only one key load (a second would block forever). We can't
    // assume the order these events will arrive in because it depends on the iteration order of a
    // HashSet of EventDispatchers inside DefaultDrmSession.
    assertThat(listener.getEvents(EVENT_DRM_KEYS_LOADED)).containsExactly(period0, period1);
    // The period1 release event is lost because it's posted to "ExoPlayerTest thread" after that
    // thread has been quit during clean-up.
    assertThat(listener.getEvents(EVENT_DRM_SESSION_RELEASED)).containsExactly(period0);
}
Also used : FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) ConcatenatingMediaSource(androidx.media3.exoplayer.source.ConcatenatingMediaSource) MediaSource(androidx.media3.exoplayer.source.MediaSource) FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) DrmSessionManager(androidx.media3.exoplayer.drm.DrmSessionManager) DefaultDrmSessionManager(androidx.media3.exoplayer.drm.DefaultDrmSessionManager) TestExoPlayerBuilder(androidx.media3.test.utils.TestExoPlayerBuilder) DefaultDrmSessionManager(androidx.media3.exoplayer.drm.DefaultDrmSessionManager) ConcatenatingMediaSource(androidx.media3.exoplayer.source.ConcatenatingMediaSource) FakeExoMediaDrm(androidx.media3.test.utils.FakeExoMediaDrm) Test(org.junit.Test)

Example 4 with DrmSession

use of androidx.media3.exoplayer.drm.DrmSession in project media by androidx.

the class DefaultDrmSessionManager method acquireSession.

// Must be called on the playback thread.
@Nullable
private DrmSession acquireSession(Looper playbackLooper, @Nullable DrmSessionEventListener.EventDispatcher eventDispatcher, Format format, boolean shouldReleasePreacquiredSessionsBeforeRetrying) {
    maybeCreateMediaDrmHandler(playbackLooper);
    if (format.drmInitData == null) {
        // Content is not encrypted.
        return maybeAcquirePlaceholderSession(MimeTypes.getTrackType(format.sampleMimeType), shouldReleasePreacquiredSessionsBeforeRetrying);
    }
    @Nullable List<SchemeData> schemeDatas = null;
    if (offlineLicenseKeySetId == null) {
        schemeDatas = getSchemeDatas(checkNotNull(format.drmInitData), uuid, false);
        if (schemeDatas.isEmpty()) {
            final MissingSchemeDataException error = new MissingSchemeDataException(uuid);
            Log.e(TAG, "DRM error", error);
            if (eventDispatcher != null) {
                eventDispatcher.drmSessionManagerError(error);
            }
            return new ErrorStateDrmSession(new DrmSessionException(error, PlaybackException.ERROR_CODE_DRM_CONTENT_ERROR));
        }
    }
    @Nullable DefaultDrmSession session;
    if (!multiSession) {
        session = noMultiSessionDrmSession;
    } else {
        // Only use an existing session if it has matching init data.
        session = null;
        for (DefaultDrmSession existingSession : sessions) {
            if (Util.areEqual(existingSession.schemeDatas, schemeDatas)) {
                session = existingSession;
                break;
            }
        }
    }
    if (session == null) {
        // Create a new session.
        session = createAndAcquireSessionWithRetry(schemeDatas, /* isPlaceholderSession= */
        false, eventDispatcher, shouldReleasePreacquiredSessionsBeforeRetrying);
        if (!multiSession) {
            noMultiSessionDrmSession = session;
        }
        sessions.add(session);
    } else {
        session.acquire(eventDispatcher);
    }
    return session;
}
Also used : DrmSessionException(androidx.media3.exoplayer.drm.DrmSession.DrmSessionException) SchemeData(androidx.media3.common.DrmInitData.SchemeData) Nullable(androidx.annotation.Nullable) Nullable(androidx.annotation.Nullable)

Example 5 with DrmSession

use of androidx.media3.exoplayer.drm.DrmSession in project media by androidx.

the class DefaultDrmSessionManagerTest method managerRelease_keepaliveDisabled_doesntReleaseAnySessions.

@Test(timeout = 10_000)
public void managerRelease_keepaliveDisabled_doesntReleaseAnySessions() throws Exception {
    FakeExoMediaDrm.LicenseServer licenseServer = FakeExoMediaDrm.LicenseServer.allowingSchemeDatas(DRM_SCHEME_DATAS);
    DrmSessionManager drmSessionManager = new DefaultDrmSessionManager.Builder().setUuidAndExoMediaDrmProvider(DRM_SCHEME_UUID, uuid -> new FakeExoMediaDrm()).setSessionKeepaliveMs(C.TIME_UNSET).build(/* mediaDrmCallback= */
    licenseServer);
    drmSessionManager.prepare();
    drmSessionManager.setPlayer(/* playbackLooper= */
    Looper.myLooper(), PlayerId.UNSET);
    DrmSession drmSession = checkNotNull(drmSessionManager.acquireSession(/* eventDispatcher= */
    null, FORMAT_WITH_DRM_INIT_DATA));
    waitForOpenedWithKeys(drmSession);
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
    // Release the manager, the session should still be open (though it's unusable because
    // the underlying ExoMediaDrm is released).
    drmSessionManager.release();
    assertThat(drmSession.getState()).isEqualTo(DrmSession.STATE_OPENED_WITH_KEYS);
}
Also used : FakeExoMediaDrm(androidx.media3.test.utils.FakeExoMediaDrm) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)18 FakeExoMediaDrm (androidx.media3.test.utils.FakeExoMediaDrm)16 AppManagedProvider (androidx.media3.exoplayer.drm.ExoMediaDrm.AppManagedProvider)7 Nullable (androidx.annotation.Nullable)5 DrmSessionReference (androidx.media3.exoplayer.drm.DrmSessionManager.DrmSessionReference)5 MediaSource (androidx.media3.exoplayer.source.MediaSource)4 DrmInitData (androidx.media3.common.DrmInitData)3 DrmSession (androidx.media3.exoplayer.drm.DrmSession)3 DrmSessionException (androidx.media3.exoplayer.drm.DrmSession.DrmSessionException)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 Looper (android.os.Looper)2 C (androidx.media3.common.C)2 Format (androidx.media3.common.Format)2 MimeTypes (androidx.media3.common.MimeTypes)2 Assertions.checkNotNull (androidx.media3.common.util.Assertions.checkNotNull)2 Util (androidx.media3.common.util.Util)2 PlayerId (androidx.media3.exoplayer.analytics.PlayerId)2 TestUtil (androidx.media3.test.utils.TestUtil)2 AndroidJUnit4 (androidx.test.ext.junit.runners.AndroidJUnit4)2 ImmutableList (com.google.common.collect.ImmutableList)2