From 1bad403eecc8a416aa7c98e6de250a004ec0f3f2 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Fri, 30 Jul 2021 11:36:10 +0100 Subject: [PATCH] Add fallback case for provisioning errors PiperOrigin-RevId: 387772641 --- .../exoplayer2/drm/DefaultDrmSession.java | 23 +++++++---- .../android/exoplayer2/drm/DrmUtil.java | 38 +++++++++++++++---- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java index 96389b018f..ca7a657a0f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSession.java @@ -238,7 +238,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } public void onProvisionError(Exception error, boolean thrownByExoMediaDrm) { - onError(error, thrownByExoMediaDrm); + onError( + error, + thrownByExoMediaDrm + ? DrmUtil.ERROR_SOURCE_EXO_MEDIA_DRM + : DrmUtil.ERROR_SOURCE_PROVISIONING); } // DrmSession implementation. @@ -361,7 +365,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } catch (NotProvisionedException e) { provisioningManager.provisionRequired(this); } catch (Exception e) { - onError(e, /* thrownByExoMediaDrm= */ true); + onError(e, DrmUtil.ERROR_SOURCE_EXO_MEDIA_DRM); } return false; @@ -411,7 +415,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; + licenseDurationRemainingSec); postKeyRequest(sessionId, ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry); } else if (licenseDurationRemainingSec <= 0) { - onError(new KeysExpiredException(), /* thrownByExoMediaDrm= */ false); + onError(new KeysExpiredException(), DrmUtil.ERROR_SOURCE_LICENSE_ACQUISITION); } else { state = STATE_OPENED_WITH_KEYS; dispatchEvent(DrmSessionEventListener.EventDispatcher::drmKeysRestored); @@ -439,7 +443,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; mediaDrm.restoreKeys(sessionId, offlineLicenseKeySetId); return true; } catch (Exception e) { - onError(e, /* thrownByExoMediaDrm= */ true); + onError(e, DrmUtil.ERROR_SOURCE_EXO_MEDIA_DRM); } return false; } @@ -508,14 +512,17 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; if (e instanceof NotProvisionedException) { provisioningManager.provisionRequired(this); } else { - onError(e, thrownByExoMediaDrm); + onError( + e, + thrownByExoMediaDrm + ? DrmUtil.ERROR_SOURCE_EXO_MEDIA_DRM + : DrmUtil.ERROR_SOURCE_LICENSE_ACQUISITION); } } - private void onError(Exception e, boolean thrownByExoMediaDrm) { + private void onError(Exception e, @DrmUtil.ErrorSource int errorSource) { lastException = - new DrmSessionException( - e, DrmUtil.getErrorCodeForMediaDrmException(e, thrownByExoMediaDrm)); + new DrmSessionException(e, DrmUtil.getErrorCodeForMediaDrmException(e, errorSource)); Log.e(TAG, "DRM session error", e); dispatchEvent(eventDispatcher -> eventDispatcher.drmSessionManagerError(e)); if (state != STATE_OPENED_WITH_KEYS) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmUtil.java index 19e5aa844e..cb92010110 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/drm/DrmUtil.java @@ -20,30 +20,50 @@ import android.media.MediaDrm; import android.media.MediaDrmResetException; import android.media.NotProvisionedException; import androidx.annotation.DoNotInline; +import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.util.Util; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** DRM-related utility methods. */ public final class DrmUtil { + /** Identifies the operation which caused a DRM-related error. */ + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef( + value = { + ERROR_SOURCE_EXO_MEDIA_DRM, + ERROR_SOURCE_LICENSE_ACQUISITION, + ERROR_SOURCE_PROVISIONING + }) + public @interface ErrorSource {} + + /** Corresponds to failures caused by an {@link ExoMediaDrm} method call. */ + public static final int ERROR_SOURCE_EXO_MEDIA_DRM = 1; + /** Corresponds to failures caused by an operation related to obtaining DRM licenses. */ + public static final int ERROR_SOURCE_LICENSE_ACQUISITION = 2; + /** Corresponds to failures caused by an operation related to provisioning the device. */ + public static final int ERROR_SOURCE_PROVISIONING = 3; + /** * Returns the {@link PlaybackException.ErrorCode} that corresponds to the given DRM-related * exception. * * @param exception The DRM-related exception for which to obtain a corresponding {@link * PlaybackException.ErrorCode}. - * @param thrownByExoMediaDrm Whether the given exception originated in a {@link ExoMediaDrm} - * method. Exceptions that did not originate in {@link ExoMediaDrm} are assumed to originate - * in the license request. + * @param errorSource The {@link ErrorSource} for the given {@code exception}. * @return The {@link PlaybackException.ErrorCode} that corresponds to the given DRM-related * exception. */ @PlaybackException.ErrorCode public static int getErrorCodeForMediaDrmException( - Exception exception, boolean thrownByExoMediaDrm) { + Exception exception, @ErrorSource int errorSource) { if (Util.SDK_INT >= 21 && PlatformOperationsWrapperV21.isMediaDrmStateException(exception)) { return PlatformOperationsWrapperV21.mediaDrmStateExceptionToErrorCode(exception); } else if (Util.SDK_INT >= 23 @@ -61,13 +81,17 @@ public final class DrmUtil { return PlaybackException.ERROR_CODE_DRM_CONTENT_ERROR; } else if (exception instanceof KeysExpiredException) { return PlaybackException.ERROR_CODE_DRM_LICENSE_EXPIRED; - } else if (thrownByExoMediaDrm) { + } else if (errorSource == ERROR_SOURCE_EXO_MEDIA_DRM) { // A MediaDrm exception was thrown but it was impossible to determine the cause. Because no // better diagnosis tools were provided, we treat this as a system error. return PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR; - } else { - // The error happened during the license request. + } else if (errorSource == ERROR_SOURCE_LICENSE_ACQUISITION) { return PlaybackException.ERROR_CODE_DRM_LICENSE_ACQUISITION_FAILED; + } else if (errorSource == ERROR_SOURCE_PROVISIONING) { + return PlaybackException.ERROR_CODE_DRM_PROVISIONING_FAILED; + } else { + // Should never happen. + throw new IllegalArgumentException(); } }