mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Move DRM error code assignment into DefaultDrmSession
PiperOrigin-RevId: 384280087
This commit is contained in:
parent
8451be1b0b
commit
cdaf3e4e99
@ -19,10 +19,6 @@ import static com.google.android.exoplayer2.util.Util.castNonNull;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import android.media.DeniedByServerException;
|
||||
import android.media.MediaDrm;
|
||||
import android.media.MediaDrmResetException;
|
||||
import android.media.NotProvisionedException;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
@ -43,9 +39,7 @@ import com.google.android.exoplayer2.Player.PlayWhenReadyChangeReason;
|
||||
import com.google.android.exoplayer2.Player.PlaybackSuppressionReason;
|
||||
import com.google.android.exoplayer2.Player.RepeatMode;
|
||||
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.DrmSession;
|
||||
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
@ -590,27 +584,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
playbackInfo = playbackInfo.copyWithPlaybackError(e);
|
||||
}
|
||||
} catch (DrmSession.DrmSessionException e) {
|
||||
@Nullable Throwable cause = e.getCause();
|
||||
@ErrorCode int errorCode;
|
||||
if (Util.SDK_INT >= 21 && PlatformOperationsWrapperV21.isMediaDrmStateException(cause)) {
|
||||
errorCode = PlatformOperationsWrapperV21.mediaDrmStateExceptionToErrorCode(cause);
|
||||
} else if (Util.SDK_INT >= 23
|
||||
&& PlatformOperationsWrapperV23.isMediaDrmResetException(cause)) {
|
||||
errorCode = PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR;
|
||||
} else if (Util.SDK_INT >= 18
|
||||
&& PlatformOperationsWrapperV18.isNotProvisionedException(cause)) {
|
||||
errorCode = PlaybackException.ERROR_CODE_DRM_PROVISIONING_FAILED;
|
||||
} else if (Util.SDK_INT >= 18
|
||||
&& PlatformOperationsWrapperV18.isDeniedByServerException(cause)) {
|
||||
errorCode = PlaybackException.ERROR_CODE_DRM_DEVICE_REVOKED;
|
||||
} else if (cause instanceof UnsupportedDrmException) {
|
||||
errorCode = PlaybackException.ERROR_CODE_DRM_SCHEME_UNSUPPORTED;
|
||||
} else if (cause instanceof DefaultDrmSessionManager.MissingSchemeDataException) {
|
||||
errorCode = PlaybackException.ERROR_CODE_DRM_CONTENT_ERROR;
|
||||
} else {
|
||||
errorCode = PlaybackException.ERROR_CODE_DRM_UNSPECIFIED;
|
||||
}
|
||||
handleIoException(e, errorCode);
|
||||
handleIoException(e, e.errorCode);
|
||||
} catch (FileDataSource.FileDataSourceException e) {
|
||||
@Nullable Throwable cause = e.getCause();
|
||||
@ErrorCode int errorCode;
|
||||
@ -3092,20 +3066,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(18)
|
||||
private static final class PlatformOperationsWrapperV18 {
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isNotProvisionedException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof NotProvisionedException;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isDeniedByServerException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof DeniedByServerException;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(21)
|
||||
private static final class PlatformOperationsWrapperV21 {
|
||||
|
||||
@ -3113,28 +3073,5 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
public static boolean isPermissionError(@Nullable Throwable e) {
|
||||
return e instanceof ErrnoException && ((ErrnoException) e).errno == OsConstants.EACCES;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isMediaDrmStateException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof MediaDrm.MediaDrmStateException;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
@ErrorCode
|
||||
public static int mediaDrmStateExceptionToErrorCode(Throwable throwable) {
|
||||
@Nullable
|
||||
String diagnosticsInfo = ((MediaDrm.MediaDrmStateException) throwable).getDiagnosticInfo();
|
||||
int drmErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
|
||||
return C.getErrorCodeForMediaDrmErrorCode(drmErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(23)
|
||||
private static final class PlatformOperationsWrapperV23 {
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isMediaDrmResetException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof MediaDrmResetException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,9 @@ import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.media.DeniedByServerException;
|
||||
import android.media.MediaDrm;
|
||||
import android.media.MediaDrmResetException;
|
||||
import android.media.NotProvisionedException;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@ -26,6 +29,7 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Pair;
|
||||
import androidx.annotation.DoNotInline;
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
@ -83,8 +87,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
* Called by a session when it fails to perform a provisioning operation.
|
||||
*
|
||||
* @param error The error that occurred.
|
||||
* @param thrownByExoMediaDrm Whether the error originated in an {@link ExoMediaDrm} operation.
|
||||
* False when the error originated in the provisioning request.
|
||||
*/
|
||||
void onProvisionError(Exception error);
|
||||
void onProvisionError(Exception error, boolean thrownByExoMediaDrm);
|
||||
|
||||
/** Called by a session when it successfully completes a provisioning operation. */
|
||||
void onProvisionCompleted();
|
||||
@ -236,8 +242,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
}
|
||||
}
|
||||
|
||||
public void onProvisionError(Exception error) {
|
||||
onError(error);
|
||||
public void onProvisionError(Exception error, boolean thrownByExoMediaDrm) {
|
||||
onError(error, thrownByExoMediaDrm);
|
||||
}
|
||||
|
||||
// DrmSession implementation.
|
||||
@ -360,7 +366,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
} catch (NotProvisionedException e) {
|
||||
provisioningManager.provisionRequired(this);
|
||||
} catch (Exception e) {
|
||||
onError(e);
|
||||
onError(e, /* thrownByExoMediaDrm= */ true);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -374,14 +380,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
currentProvisionRequest = null;
|
||||
|
||||
if (response instanceof Exception) {
|
||||
provisioningManager.onProvisionError((Exception) response);
|
||||
provisioningManager.onProvisionError((Exception) response, /* thrownByExoMediaDrm= */ false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mediaDrm.provideProvisionResponse((byte[]) response);
|
||||
} catch (Exception e) {
|
||||
provisioningManager.onProvisionError(e);
|
||||
provisioningManager.onProvisionError(e, /* thrownByExoMediaDrm= */ true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -410,7 +416,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
+ licenseDurationRemainingSec);
|
||||
postKeyRequest(sessionId, ExoMediaDrm.KEY_TYPE_OFFLINE, allowRetry);
|
||||
} else if (licenseDurationRemainingSec <= 0) {
|
||||
onError(new KeysExpiredException());
|
||||
onError(new KeysExpiredException(), /* thrownByExoMediaDrm= */ false);
|
||||
} else {
|
||||
state = STATE_OPENED_WITH_KEYS;
|
||||
dispatchEvent(DrmSessionEventListener.EventDispatcher::drmKeysRestored);
|
||||
@ -438,7 +444,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
mediaDrm.restoreKeys(sessionId, offlineLicenseKeySetId);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
onError(e);
|
||||
onError(e, /* thrownByExoMediaDrm= */ true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -458,7 +464,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
Util.castNonNull(requestHandler)
|
||||
.post(MSG_KEYS, Assertions.checkNotNull(currentKeyRequest), allowRetry);
|
||||
} catch (Exception e) {
|
||||
onKeysError(e);
|
||||
onKeysError(e, /* thrownByExoMediaDrm= */ true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -470,7 +476,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
currentKeyRequest = null;
|
||||
|
||||
if (response instanceof Exception) {
|
||||
onKeysError((Exception) response);
|
||||
onKeysError((Exception) response, /* thrownByExoMediaDrm= */ false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -492,7 +498,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
dispatchEvent(DrmSessionEventListener.EventDispatcher::drmKeysLoaded);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
onKeysError(e);
|
||||
onKeysError(e, /* thrownByExoMediaDrm= */ true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,17 +509,17 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
}
|
||||
}
|
||||
|
||||
private void onKeysError(Exception e) {
|
||||
private void onKeysError(Exception e, boolean thrownByExoMediaDrm) {
|
||||
if (e instanceof NotProvisionedException) {
|
||||
provisioningManager.provisionRequired(this);
|
||||
} else {
|
||||
onError(e);
|
||||
onError(e, thrownByExoMediaDrm);
|
||||
}
|
||||
}
|
||||
|
||||
private void onError(final Exception e) {
|
||||
// TODO(internal b/184262323): Add an argument here which takes the error code from the caller.
|
||||
lastException = new DrmSessionException(e, PlaybackException.ERROR_CODE_DRM_UNSPECIFIED);
|
||||
private void onError(Exception e, boolean thrownByExoMediaDrm) {
|
||||
lastException =
|
||||
new DrmSessionException(e, getErrorCodeForMediaDrmException(e, thrownByExoMediaDrm));
|
||||
Log.e(TAG, "DRM session error", e);
|
||||
dispatchEvent(eventDispatcher -> eventDispatcher.drmSessionManagerError(e));
|
||||
if (state != STATE_OPENED_WITH_KEYS) {
|
||||
@ -533,6 +539,35 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
}
|
||||
}
|
||||
|
||||
@PlaybackException.ErrorCode
|
||||
private static int getErrorCodeForMediaDrmException(
|
||||
Exception exception, boolean thrownByExoMediaDrm) {
|
||||
if (Util.SDK_INT >= 21 && PlatformOperationsWrapperV21.isMediaDrmStateException(exception)) {
|
||||
return PlatformOperationsWrapperV21.mediaDrmStateExceptionToErrorCode(exception);
|
||||
} else if (Util.SDK_INT >= 23
|
||||
&& PlatformOperationsWrapperV23.isMediaDrmResetException(exception)) {
|
||||
return PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR;
|
||||
} else if (Util.SDK_INT >= 18
|
||||
&& PlatformOperationsWrapperV18.isNotProvisionedException(exception)) {
|
||||
return PlaybackException.ERROR_CODE_DRM_PROVISIONING_FAILED;
|
||||
} else if (Util.SDK_INT >= 18
|
||||
&& PlatformOperationsWrapperV18.isDeniedByServerException(exception)) {
|
||||
return PlaybackException.ERROR_CODE_DRM_DEVICE_REVOKED;
|
||||
} else if (exception instanceof UnsupportedDrmException) {
|
||||
return PlaybackException.ERROR_CODE_DRM_SCHEME_UNSUPPORTED;
|
||||
} 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;
|
||||
} else if (thrownByExoMediaDrm) {
|
||||
// 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 {
|
||||
return PlaybackException.ERROR_CODE_DRM_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal classes.
|
||||
|
||||
@SuppressLint("HandlerLeak")
|
||||
@ -678,4 +713,45 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
this.request = request;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(18)
|
||||
private static final class PlatformOperationsWrapperV18 {
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isNotProvisionedException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof NotProvisionedException;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isDeniedByServerException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof DeniedByServerException;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(21)
|
||||
private static final class PlatformOperationsWrapperV21 {
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isMediaDrmStateException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof MediaDrm.MediaDrmStateException;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
@PlaybackException.ErrorCode
|
||||
public static int mediaDrmStateExceptionToErrorCode(Throwable throwable) {
|
||||
@Nullable
|
||||
String diagnosticsInfo = ((MediaDrm.MediaDrmStateException) throwable).getDiagnosticInfo();
|
||||
int drmErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
|
||||
return C.getErrorCodeForMediaDrmErrorCode(drmErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(23)
|
||||
private static final class PlatformOperationsWrapperV23 {
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isMediaDrmResetException(@Nullable Throwable throwable) {
|
||||
return throwable instanceof MediaDrmResetException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -876,14 +876,14 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProvisionError(Exception error) {
|
||||
public void onProvisionError(Exception error, boolean thrownByExoMediaDrm) {
|
||||
provisioningSession = null;
|
||||
ImmutableList<DefaultDrmSession> sessionsToNotify =
|
||||
ImmutableList.copyOf(sessionsAwaitingProvisioning);
|
||||
// Clear the list before calling onProvisionError in case provisioning is re-requested.
|
||||
sessionsAwaitingProvisioning.clear();
|
||||
for (DefaultDrmSession session : sessionsToNotify) {
|
||||
session.onProvisionError(error);
|
||||
session.onProvisionError(error, thrownByExoMediaDrm);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user