summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt63
-rw-r--r--media/java/android/media/MediaCodec.java61
-rw-r--r--media/java/android/media/MediaDrm.java404
3 files changed, 492 insertions, 36 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 52f2335127a4..742004b24541 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -21118,15 +21118,15 @@ package android.media {
public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
ctor public MediaCodec.CryptoException(int, @Nullable String);
method public int getErrorCode();
- field public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8
- field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
- field public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7
- field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
- field public static final int ERROR_LOST_STATE = 9; // 0x9
- field public static final int ERROR_NO_KEY = 1; // 0x1
- field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
- field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
- field public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6
+ field @Deprecated public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8
+ field @Deprecated public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
+ field @Deprecated public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7
+ field @Deprecated public static final int ERROR_KEY_EXPIRED = 2; // 0x2
+ field @Deprecated public static final int ERROR_LOST_STATE = 9; // 0x9
+ field @Deprecated public static final int ERROR_NO_KEY = 1; // 0x1
+ field @Deprecated public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
+ field @Deprecated public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
+ field @Deprecated public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6
}
public static final class MediaCodec.CryptoInfo {
@@ -21745,6 +21745,42 @@ package android.media {
method public boolean verify(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
}
+ public static final class MediaDrm.ErrorCodes {
+ field public static final int ERROR_CERTIFICATE_MALFORMED = 10; // 0xa
+ field public static final int ERROR_CERTIFICATE_MISSING = 11; // 0xb
+ field public static final int ERROR_CRYPTO_LIBRARY = 12; // 0xc
+ field public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8
+ field public static final int ERROR_GENERIC_OEM = 13; // 0xd
+ field public static final int ERROR_GENERIC_PLUGIN = 14; // 0xe
+ field public static final int ERROR_INIT_DATA = 15; // 0xf
+ field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
+ field public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7
+ field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
+ field public static final int ERROR_KEY_NOT_LOADED = 16; // 0x10
+ field public static final int ERROR_LICENSE_PARSE = 17; // 0x11
+ field public static final int ERROR_LICENSE_POLICY = 18; // 0x12
+ field public static final int ERROR_LICENSE_RELEASE = 19; // 0x13
+ field public static final int ERROR_LICENSE_REQUEST_REJECTED = 20; // 0x14
+ field public static final int ERROR_LICENSE_RESTORE = 21; // 0x15
+ field public static final int ERROR_LICENSE_STATE = 22; // 0x16
+ field public static final int ERROR_LOST_STATE = 9; // 0x9
+ field public static final int ERROR_MEDIA_FRAMEWORK = 23; // 0x17
+ field public static final int ERROR_NO_KEY = 1; // 0x1
+ field public static final int ERROR_PROVISIONING_CERTIFICATE = 24; // 0x18
+ field public static final int ERROR_PROVISIONING_CONFIG = 25; // 0x19
+ field public static final int ERROR_PROVISIONING_PARSE = 26; // 0x1a
+ field public static final int ERROR_PROVISIONING_RETRY = 27; // 0x1b
+ field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
+ field public static final int ERROR_RESOURCE_CONTENTION = 28; // 0x1c
+ field public static final int ERROR_SECURE_STOP_RELEASE = 29; // 0x1d
+ field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
+ field public static final int ERROR_STORAGE_READ = 30; // 0x1e
+ field public static final int ERROR_STORAGE_WRITE = 31; // 0x1f
+ field public static final int ERROR_UNKNOWN = 0; // 0x0
+ field public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6
+ field public static final int ERROR_ZERO_SUBSAMPLES = 32; // 0x20
+ }
+
@Deprecated @IntDef({android.media.MediaDrm.HDCP_LEVEL_UNKNOWN, android.media.MediaDrm.HDCP_NONE, android.media.MediaDrm.HDCP_V1, android.media.MediaDrm.HDCP_V2, android.media.MediaDrm.HDCP_V2_1, android.media.MediaDrm.HDCP_V2_2, android.media.MediaDrm.HDCP_V2_3, android.media.MediaDrm.HDCP_NO_DIGITAL_OUTPUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface MediaDrm.HdcpLevel {
}
@@ -21778,6 +21814,8 @@ package android.media {
public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
method @NonNull public String getDiagnosticInfo();
+ method public int getErrorCode();
+ method public boolean isTransient();
}
public static final class MediaDrm.MetricsConstants {
@@ -21844,9 +21882,10 @@ package android.media {
public static final class MediaDrm.SessionException extends java.lang.RuntimeException {
ctor public MediaDrm.SessionException(int, @Nullable String);
- method public int getErrorCode();
- field public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1
- field public static final int ERROR_UNKNOWN = 0; // 0x0
+ method @Deprecated public int getErrorCode();
+ method public boolean isTransient();
+ field @Deprecated public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1
+ field @Deprecated public static final int ERROR_UNKNOWN = 0; // 0x0
}
public class MediaDrmException extends java.lang.Exception {
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 607c8f11e01a..cf31e4141a6d 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2414,37 +2414,44 @@ final public class MediaCodec implements PlaybackComponent {
* This indicates that the requested key was not found when trying to
* perform a decrypt operation. The operation can be retried after adding
* the correct decryption key.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_NO_KEY}.
*/
- public static final int ERROR_NO_KEY = 1;
+ public static final int ERROR_NO_KEY = MediaDrm.ErrorCodes.ERROR_NO_KEY;
/**
* This indicates that the key used for decryption is no longer
* valid due to license term expiration. The operation can be retried
* after updating the expired keys.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_KEY_EXPIRED}.
*/
- public static final int ERROR_KEY_EXPIRED = 2;
+ public static final int ERROR_KEY_EXPIRED = MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED;
/**
* This indicates that a required crypto resource was not able to be
* allocated while attempting the requested operation. The operation
* can be retried if the app is able to release resources.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_RESOURCE_BUSY}
*/
- public static final int ERROR_RESOURCE_BUSY = 3;
+ public static final int ERROR_RESOURCE_BUSY = MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY;
/**
* This indicates that the output protection levels supported by the
* device are not sufficient to meet the requirements set by the
* content owner in the license policy.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_OUTPUT_PROTECTION}
*/
- public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
+ public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION =
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION;
/**
* This indicates that decryption was attempted on a session that is
* not opened, which could be due to a failure to open the session,
* closing the session prematurely, or the session being reclaimed
* by the resource manager.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_SESSION_NOT_OPENED}
*/
- public static final int ERROR_SESSION_NOT_OPENED = 5;
+ public static final int ERROR_SESSION_NOT_OPENED =
+ MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED;
/**
* This indicates that an operation was attempted that could not be
@@ -2453,23 +2460,28 @@ final public class MediaCodec implements PlaybackComponent {
* device security features that aren't supported by the device,
* or due to an internal error in the crypto system that prevents
* the specified security policy from being met.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_UNSUPPORTED_OPERATION}
*/
- public static final int ERROR_UNSUPPORTED_OPERATION = 6;
+ public static final int ERROR_UNSUPPORTED_OPERATION =
+ MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION;
/**
* This indicates that the security level of the device is not
* sufficient to meet the requirements set by the content owner
* in the license policy.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_SECURITY}
*/
- public static final int ERROR_INSUFFICIENT_SECURITY = 7;
+ public static final int ERROR_INSUFFICIENT_SECURITY =
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY;
/**
* This indicates that the video frame being decrypted exceeds
* the size of the device's protected output buffers. When
* encountering this error the app should try playing content
* of a lower resolution.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_FRAME_TOO_LARGE}
*/
- public static final int ERROR_FRAME_TOO_LARGE = 8;
+ public static final int ERROR_FRAME_TOO_LARGE = MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE;
/**
* This error indicates that session state has been
@@ -2477,26 +2489,37 @@ final public class MediaCodec implements PlaybackComponent {
* of retaining crypto session state across device
* suspend/resume. The session must be closed and a new
* session opened to resume operation.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_LOST_STATE}
*/
- public static final int ERROR_LOST_STATE = 9;
+ public static final int ERROR_LOST_STATE = MediaDrm.ErrorCodes.ERROR_LOST_STATE;
/** @hide */
@IntDef({
- ERROR_NO_KEY,
- ERROR_KEY_EXPIRED,
- ERROR_RESOURCE_BUSY,
- ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
- ERROR_SESSION_NOT_OPENED,
- ERROR_UNSUPPORTED_OPERATION,
- ERROR_INSUFFICIENT_SECURITY,
- ERROR_FRAME_TOO_LARGE,
- ERROR_LOST_STATE
+ MediaDrm.ErrorCodes.ERROR_NO_KEY,
+ MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED,
+ MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY,
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
+ MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED,
+ MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION,
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY,
+ MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE,
+ MediaDrm.ErrorCodes.ERROR_LOST_STATE,
+ MediaDrm.ErrorCodes.ERROR_GENERIC_OEM,
+ MediaDrm.ErrorCodes.ERROR_GENERIC_PLUGIN,
+ MediaDrm.ErrorCodes.ERROR_LICENSE_PARSE,
+ MediaDrm.ErrorCodes.ERROR_MEDIA_FRAMEWORK,
+ MediaDrm.ErrorCodes.ERROR_ZERO_SUBSAMPLES
})
@Retention(RetentionPolicy.SOURCE)
public @interface CryptoErrorCode {}
/**
- * Retrieve the error code associated with a CryptoException
+ * Returns error code associated with this {@link CryptoException}.
+ * <p>
+ * Please refer to {@link MediaDrm.ErrorCodes} for the general error
+ * handling strategy and details about each possible return value.
+ *
+ * @return an error code defined in {@link MediaDrm.ErrorCodes}.
*/
@CryptoErrorCode
public int getErrorCode() {
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index ea5fe39ccc08..f7467a636024 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -297,9 +297,363 @@ public final class MediaDrm implements AutoCloseable {
}
/**
- * Thrown when an unrecoverable failure occurs during a MediaDrm operation.
- * Extends java.lang.IllegalStateException with the addition of an error
+ * Error codes that may be returned from {@link
+ * MediaDrmStateException#getErrorCode()} and {@link
+ * MediaCodec.CryptoException#getErrorCode()}
+ * <p>
+ * The description of each error code includes steps that may be taken to
+ * resolve the error condition. For some errors however, a recovery action
+ * cannot be predetermined. The description of those codes refers to a
+ * general strategy for handling the error condition programmatically, which
+ * is to try the following in listed order until successful:
+ * <ol>
+ * <li> retry the operation </li>
+ * <li> if the operation is related to a session, {@link
+ * #closeSession(byte[]) close} the session, {@link #openSession() open} a
+ * new session, and retry the operation </li>
+ * <li> {@link #close() close} the {@link MediaDrm} instance and any other
+ * related components such as the {@link MediaCodec codec} and retry
+ * playback, or </li>
+ * <li> try using a different configuration of the {@link MediaDrm} plugin,
+ * such as a different {@link #openSession(int) security level}. </li>
+ * </ol>
+ * <p>
+ * If the problem still persists after all the aforementioned steps, please
+ * report the failure to the {@link MediaDrm} plugin vendor along with the
+ * {@link LogMessage log messages} returned by {@link
+ * MediaDrm#getLogMessages()}, and a bugreport if possible.
+ */
+ public final static class ErrorCodes {
+ private ErrorCodes() {}
+
+ /**
+ * ERROR_UNKNOWN is used where no other defined error code is applicable
+ * to the current failure.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_UNKNOWN = 0;
+
+ /**
+ * The requested key was not found when trying to perform a decrypt
+ * operation.
+ * <p>
+ * The operation can be retried after adding the correct decryption key.
+ */
+ public static final int ERROR_NO_KEY = 1;
+
+ /**
+ * The key used for decryption is no longer valid due to license term
+ * expiration.
+ * <p>
+ * The operation can be retried after updating the expired keys.
+ */
+ public static final int ERROR_KEY_EXPIRED = 2;
+
+ /**
+ * A required crypto resource was not able to be allocated while
+ * attempting the requested operation.
+ * <p>
+ * The operation can be retried if the app is able to release resources.
+ */
+ public static final int ERROR_RESOURCE_BUSY = 3;
+
+ /**
+ * The output protection levels supported by the device are not
+ * sufficient to meet the requirements set by the content owner in the
+ * license policy.
+ */
+ public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
+
+ /**
+ * Decryption was attempted on a session that is not opened, which could
+ * be due to a failure to open the session, closing the session
+ * prematurely, the session being reclaimed by the resource manager, or
+ * a non-existent session id.
+ */
+ public static final int ERROR_SESSION_NOT_OPENED = 5;
+
+ /**
+ * An operation was attempted that could not be supported by the crypto
+ * system of the device in its current configuration.
+ * <p>
+ * This may occur when the license policy requires device security
+ * features that aren't supported by the device, or due to an internal
+ * error in the crypto system that prevents the specified security
+ * policy from being met.
+ */
+ public static final int ERROR_UNSUPPORTED_OPERATION = 6;
+
+ /**
+ * The security level of the device is not sufficient to meet the
+ * requirements set by the content owner in the license policy.
+ */
+ public static final int ERROR_INSUFFICIENT_SECURITY = 7;
+
+ /**
+ * The video frame being decrypted exceeds the size of the device's
+ * protected output buffers.
+ * <p>
+ * When encountering this error the app should try playing content
+ * of a lower resolution or skipping the problematic frame.
+ */
+ public static final int ERROR_FRAME_TOO_LARGE = 8;
+
+ /**
+ * The session state has been invalidated. This can occur on devices
+ * that are not capable of retaining crypto session state across device
+ * suspend/resume.
+ * <p>
+ * The session must be closed and a new session opened to resume
+ * operation.
+ */
+ public static final int ERROR_LOST_STATE = 9;
+
+ /**
+ * Certificate is malformed or is of the wrong type.
+ * <p>
+ * Ensure the certificate provided by the app or returned from the
+ * license server is valid. Check with the {@link MediaDrm} plugin
+ * vendor for the expected certificate format.
+ */
+ public static final int ERROR_CERTIFICATE_MALFORMED = 10;
+
+ /**
+ * Certificate has not been set.
+ * <p>
+ * Ensure the certificate has been provided by the app. Check with the
+ * {@link MediaDrm} plugin vendor for the expected method to provide
+ * {@link MediaDrm} a certificate.
+ */
+ public static final int ERROR_CERTIFICATE_MISSING = 11;
+
+ /**
+ * An error happened within the crypto library used by the drm plugin.
+ */
+ public static final int ERROR_CRYPTO_LIBRARY = 12;
+
+ /**
+ * Unexpected error reported by the device OEM subsystem.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_GENERIC_OEM = 13;
+
+ /**
+ * Unexpected internal failure in {@link MediaDrm}/{@link MediaCrypto}.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_GENERIC_PLUGIN = 14;
+
+ /**
+ * The init data parameter passed to {@link MediaDrm#getKeyRequest} is
+ * empty or invalid.
+ * <p>
+ * Init data is typically obtained from {@link
+ * MediaExtractor#getPsshInfo()} or {@link
+ * MediaExtractor#getDrmInitData()}. Check with the {@link MediaDrm}
+ * plugin vendor for the expected init data format.
+ */
+ public static final int ERROR_INIT_DATA = 15;
+
+ /**
+ * Either the key was not loaded from the license before attempting the
+ * operation, or the key ID parameter provided by the app is incorrect.
+ * <p>
+ * Ensure the proper keys are in the license, and check the key ID
+ * parameter provided by the app is correct. Check with the {@link
+ * MediaDrm} plugin vendor for the expected license format.
+ */
+ public static final int ERROR_KEY_NOT_LOADED = 16;
+
+ /**
+ * The license response was empty, fields are missing or otherwise
+ * unable to be parsed or decrypted.
+ * <p>
+ * Check for mistakes such as empty or overwritten buffers. Otherwise,
+ * check with the {@link MediaDrm} plugin vendor for the expected
+ * license format.
+ */
+ public static final int ERROR_LICENSE_PARSE = 17;
+
+ /**
+ * The operation (e.g. to renew or persist a license) is prohibited by
+ * the license policy.
+ * <p>
+ * Check the license policy configuration on the license server.
+ */
+ public static final int ERROR_LICENSE_POLICY = 18;
+
+ /**
+ * Failed to generate a release request because a field in the offline
+ * license is empty or malformed.
+ * <p>
+ * The license can't be released on the server, but the app may remove
+ * the offline license explicitly using {@link
+ * MediaDrm#removeOfflineLicense}.
+ */
+ public static final int ERROR_LICENSE_RELEASE = 19;
+
+ /**
+ * The license server detected an error in the license request.
+ * <p>
+ * Check for errors on the license server.
+ */
+ public static final int ERROR_LICENSE_REQUEST_REJECTED = 20;
+
+ /**
+ * Failed to restore an offline license because a field in the offline
+ * license is empty or malformed.
+ * <p>
+ * Try requesting the license again if the device is online.
+ */
+ public static final int ERROR_LICENSE_RESTORE = 21;
+
+ /**
+ * Offline license is in an invalid state for the attempted operation.
+ * <p>
+ * Check the sequence of API calls made that can affect offline license
+ * state. For example, this could happen when the app attempts to
+ * restore a license after it has been released.
+ */
+ public static final int ERROR_LICENSE_STATE = 22;
+
+ /**
+ * Failure in the media framework.
+ * <p>
+ * Try releasing media resources (e.g. {@link MediaCodec}, {@link
+ * MediaDrm}), and restarting playback.
+ */
+ public static final int ERROR_MEDIA_FRAMEWORK = 23;
+
+ /**
+ * Error loading the provisioned certificate.
+ * <p>
+ * Re-provisioning may resolve the problem; check with the {@link
+ * MediaDrm} plugin vendor for re-provisioning instructions. Otherwise,
+ * using a different security level may resolve the issue.
+ */
+ public static final int ERROR_PROVISIONING_CERTIFICATE = 24;
+
+ /**
+ * Required steps were not performed before provisioning was attempted.
+ * <p>
+ * Ask the {@link MediaDrm} plugin vendor for situations where this
+ * error may occur.
+ */
+ public static final int ERROR_PROVISIONING_CONFIG = 25;
+
+ /**
+ * The provisioning response was empty, fields are missing or otherwise
+ * unable to be parsed.
+ * <p>
+ * Check for mistakes such as empty or overwritten buffers. Otherwise,
+ * check with the {@link MediaDrm} plugin vendor for the expected
+ * provisioning response format.
+ */
+ public static final int ERROR_PROVISIONING_PARSE = 26;
+
+ /**
+ * Provisioning failed in a way that is likely to succeed on a
+ * subsequent attempt.
+ * <p>
+ * The app should retry the operation.
+ */
+ public static final int ERROR_PROVISIONING_RETRY = 27;
+
+ /**
+ * This indicates that apps using MediaDrm sessions are
+ * temporarily exceeding the capacity of available crypto
+ * resources.
+ * <p>
+ * The app should retry the operation later.
+ */
+ public static final int ERROR_RESOURCE_CONTENTION = 28;
+
+ /**
+ * Failed to generate a secure stop request because a field in the
+ * stored license is empty or malformed.
+ * <p>
+ * The secure stop can't be released on the server, but the app may
+ * remove it explicitly using {@link MediaDrm#removeSecureStop}.
+ */
+ public static final int ERROR_SECURE_STOP_RELEASE = 29;
+
+ /**
+ * The plugin was unable to read data from the filesystem.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_STORAGE_READ = 30;
+
+ /**
+ * The plugin was unable to write data to the filesystem.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_STORAGE_WRITE = 31;
+
+ /**
+ * {@link MediaCodec#queueSecureInputBuffer} called with 0 subsamples.
+ * <p>
+ * Check the {@link MediaCodec.CryptoInfo} object passed to {@link
+ * MediaCodec#queueSecureInputBuffer}.
+ */
+ public static final int ERROR_ZERO_SUBSAMPLES = 32;
+
+ }
+
+ /** @hide */
+ @IntDef({
+ ErrorCodes.ERROR_NO_KEY,
+ ErrorCodes.ERROR_KEY_EXPIRED,
+ ErrorCodes.ERROR_RESOURCE_BUSY,
+ ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
+ ErrorCodes.ERROR_SESSION_NOT_OPENED,
+ ErrorCodes.ERROR_UNSUPPORTED_OPERATION,
+ ErrorCodes.ERROR_INSUFFICIENT_SECURITY,
+ ErrorCodes.ERROR_FRAME_TOO_LARGE,
+ ErrorCodes.ERROR_LOST_STATE,
+ ErrorCodes.ERROR_CERTIFICATE_MALFORMED,
+ ErrorCodes.ERROR_CERTIFICATE_MISSING,
+ ErrorCodes.ERROR_CRYPTO_LIBRARY,
+ ErrorCodes.ERROR_GENERIC_OEM,
+ ErrorCodes.ERROR_GENERIC_PLUGIN,
+ ErrorCodes.ERROR_INIT_DATA,
+ ErrorCodes.ERROR_KEY_NOT_LOADED,
+ ErrorCodes.ERROR_LICENSE_PARSE,
+ ErrorCodes.ERROR_LICENSE_POLICY,
+ ErrorCodes.ERROR_LICENSE_RELEASE,
+ ErrorCodes.ERROR_LICENSE_REQUEST_REJECTED,
+ ErrorCodes.ERROR_LICENSE_RESTORE,
+ ErrorCodes.ERROR_LICENSE_STATE,
+ ErrorCodes.ERROR_MEDIA_FRAMEWORK,
+ ErrorCodes.ERROR_PROVISIONING_CERTIFICATE,
+ ErrorCodes.ERROR_PROVISIONING_CONFIG,
+ ErrorCodes.ERROR_PROVISIONING_PARSE,
+ ErrorCodes.ERROR_PROVISIONING_RETRY,
+ ErrorCodes.ERROR_SECURE_STOP_RELEASE,
+ ErrorCodes.ERROR_STORAGE_READ,
+ ErrorCodes.ERROR_STORAGE_WRITE,
+ ErrorCodes.ERROR_ZERO_SUBSAMPLES
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MediaDrmErrorCode {}
+
+ /**
+ * Thrown when a general failure occurs during a MediaDrm operation.
+ * Extends {@link IllegalStateException} with the addition of an error
* code that may be useful in diagnosing the failure.
+ * <p>
+ * Please refer to {@link ErrorCodes} for the general error handling
+ * strategy and details about each possible return value from {@link
+ * MediaDrmStateException#getErrorCode()}.
*/
public static final class MediaDrmStateException extends java.lang.IllegalStateException {
private final int mErrorCode;
@@ -320,15 +674,30 @@ public final class MediaDrm implements AutoCloseable {
}
/**
- * Retrieve the associated error code
+ * Returns error code associated with this {@link
+ * MediaDrmStateException}.
+ * <p>
+ * Please refer to {@link ErrorCodes} for the general error handling
+ * strategy and details about each possible return value.
*
- * @hide
+ * @return an error code defined in {@link MediaDrm.ErrorCodes}.
*/
+ @MediaDrmErrorCode
public int getErrorCode() {
return mErrorCode;
}
/**
+ * Returns true if the {@link MediaDrmStateException} is a transient
+ * issue, perhaps due to resource constraints, and that the operation
+ * (e.g. provisioning) may succeed on a subsequent attempt.
+ */
+ public boolean isTransient() {
+ return mErrorCode == ErrorCodes.ERROR_PROVISIONING_RETRY
+ || mErrorCode == ErrorCodes.ERROR_RESOURCE_CONTENTION;
+ }
+
+ /**
* Retrieve a developer-readable diagnostic information string
* associated with the exception. Do not show this to end-users,
* since this string will not be localized or generally comprehensible
@@ -341,7 +710,13 @@ public final class MediaDrm implements AutoCloseable {
}
/**
- * Thrown when an error occurs in any method that has a session context.
+ * {@link SessionException} is a misnomer because it may occur in methods
+ * <b>without</b> a session context.
+ * <p>
+ * A {@link SessionException} is most likely to be thrown when an operation
+ * failed in a way that is likely to succeed on a subsequent attempt; call
+ * {@link #isTransient()} to determine whether the app should retry the
+ * failing operation.
*/
public static final class SessionException extends RuntimeException {
public SessionException(int errorCode, @Nullable String detailMessage) {
@@ -351,6 +726,7 @@ public final class MediaDrm implements AutoCloseable {
/**
* The SessionException has an unknown error code.
+ * @deprecated Unused.
*/
public static final int ERROR_UNKNOWN = 0;
@@ -358,6 +734,10 @@ public final class MediaDrm implements AutoCloseable {
* This indicates that apps using MediaDrm sessions are
* temporarily exceeding the capacity of available crypto
* resources. The app should retry the operation later.
+ *
+ * @deprecated Please use {@link #isTransient()} instead of comparing
+ * the return value of {@link #getErrorCode()} against
+ * {@link SessionException#ERROR_RESOURCE_CONTENTION}.
*/
public static final int ERROR_RESOURCE_CONTENTION = 1;
@@ -370,12 +750,26 @@ public final class MediaDrm implements AutoCloseable {
/**
* Retrieve the error code associated with the SessionException
+ *
+ * @deprecated Please use {@link #isTransient()} instead of comparing
+ * the return value of {@link #getErrorCode()} against
+ * {@link SessionException#ERROR_RESOURCE_CONTENTION}.
*/
@SessionErrorCode
public int getErrorCode() {
return mErrorCode;
}
+ /**
+ * Returns true if the {@link SessionException} is a transient
+ * issue, perhaps due to resource constraints, and that the operation
+ * (e.g. provisioning, generating requests) may succeed on a subsequent
+ * attempt.
+ */
+ public boolean isTransient() {
+ return mErrorCode == ERROR_RESOURCE_CONTENTION;
+ }
+
private final int mErrorCode;
}