Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 922bdb1b authored by Jeff Tinker's avatar Jeff Tinker Committed by Android Git Automerger
Browse files

am 7020a137: Merge "MediaDrm API Updates per api council review" into mnc-dev

* commit '7020a137':
  MediaDrm API Updates per api council review
parents 46f7c233 7020a137
Loading
Loading
Loading
Loading
+11 −11
Original line number Original line Diff line number Diff line
@@ -15730,7 +15730,7 @@ package android.media {
    method public void restoreKeys(byte[], byte[]);
    method public void restoreKeys(byte[], byte[]);
    method public void setOnEventListener(android.media.MediaDrm.OnEventListener);
    method public void setOnEventListener(android.media.MediaDrm.OnEventListener);
    method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler);
    method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler);
    method public void setOnKeysChangeListener(android.media.MediaDrm.OnKeysChangeListener, android.os.Handler);
    method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
    method public void setPropertyByteArray(java.lang.String, byte[]);
    method public void setPropertyByteArray(java.lang.String, byte[]);
    method public void setPropertyString(java.lang.String, java.lang.String);
    method public void setPropertyString(java.lang.String, java.lang.String);
    field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
    field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
@@ -15738,11 +15738,6 @@ package android.media {
    field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
    field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
    field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
    field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
    field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
    field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
    field public static final int KEY_STATUS_EXPIRED = 1; // 0x1
    field public static final int KEY_STATUS_INTERNAL_ERROR = 4; // 0x4
    field public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
    field public static final int KEY_STATUS_PENDING = 3; // 0x3
    field public static final int KEY_STATUS_USABLE = 0; // 0x0
    field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
    field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
    field public static final int KEY_TYPE_RELEASE = 3; // 0x3
    field public static final int KEY_TYPE_RELEASE = 3; // 0x3
    field public static final int KEY_TYPE_STREAMING = 1; // 0x1
    field public static final int KEY_TYPE_STREAMING = 1; // 0x1
@@ -15751,9 +15746,6 @@ package android.media {
    field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
    field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
    field public static final java.lang.String PROPERTY_VENDOR = "vendor";
    field public static final java.lang.String PROPERTY_VENDOR = "vendor";
    field public static final java.lang.String PROPERTY_VERSION = "version";
    field public static final java.lang.String PROPERTY_VERSION = "version";
    field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
    field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
    field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
  }
  }
  public final class MediaDrm.CryptoSession {
  public final class MediaDrm.CryptoSession {
@@ -15767,11 +15759,19 @@ package android.media {
    method public byte[] getData();
    method public byte[] getData();
    method public java.lang.String getDefaultUrl();
    method public java.lang.String getDefaultUrl();
    method public int getRequestType();
    method public int getRequestType();
    field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
    field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
    field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
  }
  }
  public static final class MediaDrm.KeyStatus {
  public static final class MediaDrm.KeyStatus {
    method public byte[] getKeyId();
    method public byte[] getKeyId();
    method public int getStatusCode();
    method public int getStatusCode();
    field public static final int STATUS_EXPIRED = 1; // 0x1
    field public static final int STATUS_INTERNAL_ERROR = 4; // 0x4
    field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
    field public static final int STATUS_PENDING = 3; // 0x3
    field public static final int STATUS_USABLE = 0; // 0x0
  }
  }
  public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
  public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -15786,8 +15786,8 @@ package android.media {
    method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long);
    method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long);
  }
  }
  public static abstract interface MediaDrm.OnKeysChangeListener {
  public static abstract interface MediaDrm.OnKeyStatusChangeListener {
    method public abstract void onKeysChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
    method public abstract void onKeyStatusChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
  }
  }
  public static final class MediaDrm.ProvisionRequest {
  public static final class MediaDrm.ProvisionRequest {
+11 −11
Original line number Original line Diff line number Diff line
@@ -16967,7 +16967,7 @@ package android.media {
    method public void restoreKeys(byte[], byte[]);
    method public void restoreKeys(byte[], byte[]);
    method public void setOnEventListener(android.media.MediaDrm.OnEventListener);
    method public void setOnEventListener(android.media.MediaDrm.OnEventListener);
    method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler);
    method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler);
    method public void setOnKeysChangeListener(android.media.MediaDrm.OnKeysChangeListener, android.os.Handler);
    method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
    method public void setPropertyByteArray(java.lang.String, byte[]);
    method public void setPropertyByteArray(java.lang.String, byte[]);
    method public void setPropertyString(java.lang.String, java.lang.String);
    method public void setPropertyString(java.lang.String, java.lang.String);
    method public void unprovisionDevice();
    method public void unprovisionDevice();
@@ -16976,11 +16976,6 @@ package android.media {
    field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
    field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
    field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
    field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
    field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
    field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
    field public static final int KEY_STATUS_EXPIRED = 1; // 0x1
    field public static final int KEY_STATUS_INTERNAL_ERROR = 4; // 0x4
    field public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
    field public static final int KEY_STATUS_PENDING = 3; // 0x3
    field public static final int KEY_STATUS_USABLE = 0; // 0x0
    field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
    field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
    field public static final int KEY_TYPE_RELEASE = 3; // 0x3
    field public static final int KEY_TYPE_RELEASE = 3; // 0x3
    field public static final int KEY_TYPE_STREAMING = 1; // 0x1
    field public static final int KEY_TYPE_STREAMING = 1; // 0x1
@@ -16989,9 +16984,6 @@ package android.media {
    field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
    field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
    field public static final java.lang.String PROPERTY_VENDOR = "vendor";
    field public static final java.lang.String PROPERTY_VENDOR = "vendor";
    field public static final java.lang.String PROPERTY_VERSION = "version";
    field public static final java.lang.String PROPERTY_VERSION = "version";
    field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
    field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
    field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
  }
  }
  public final class MediaDrm.CryptoSession {
  public final class MediaDrm.CryptoSession {
@@ -17005,11 +16997,19 @@ package android.media {
    method public byte[] getData();
    method public byte[] getData();
    method public java.lang.String getDefaultUrl();
    method public java.lang.String getDefaultUrl();
    method public int getRequestType();
    method public int getRequestType();
    field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
    field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
    field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
  }
  }
  public static final class MediaDrm.KeyStatus {
  public static final class MediaDrm.KeyStatus {
    method public byte[] getKeyId();
    method public byte[] getKeyId();
    method public int getStatusCode();
    method public int getStatusCode();
    field public static final int STATUS_EXPIRED = 1; // 0x1
    field public static final int STATUS_INTERNAL_ERROR = 4; // 0x4
    field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
    field public static final int STATUS_PENDING = 3; // 0x3
    field public static final int STATUS_USABLE = 0; // 0x0
  }
  }
  public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
  public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -17024,8 +17024,8 @@ package android.media {
    method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long);
    method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long);
  }
  }
  public static abstract interface MediaDrm.OnKeysChangeListener {
  public static abstract interface MediaDrm.OnKeyStatusChangeListener {
    method public abstract void onKeysChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
    method public abstract void onKeyStatusChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
  }
  }
  public static final class MediaDrm.ProvisionRequest {
  public static final class MediaDrm.ProvisionRequest {
+85 −80
Original line number Original line Diff line number Diff line
@@ -110,10 +110,10 @@ public final class MediaDrm {
    private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES;
    private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES;


    private EventHandler mEventHandler;
    private EventHandler mEventHandler;
    private EventHandler mOnKeysChangeEventHandler;
    private EventHandler mOnKeyStatusChangeEventHandler;
    private EventHandler mOnExpirationUpdateEventHandler;
    private EventHandler mOnExpirationUpdateEventHandler;
    private OnEventListener mOnEventListener;
    private OnEventListener mOnEventListener;
    private OnKeysChangeListener mOnKeysChangeListener;
    private OnKeyStatusChangeListener mOnKeyStatusChangeListener;
    private OnExpirationUpdateListener mOnExpirationUpdateListener;
    private OnExpirationUpdateListener mOnExpirationUpdateListener;


    private long mNativeContext;
    private long mNativeContext;
@@ -297,8 +297,8 @@ public final class MediaDrm {
     * @param handler the handler on which the listener should be invoked, or
     * @param handler the handler on which the listener should be invoked, or
     *     null if the listener should be invoked on the calling thread's looper.
     *     null if the listener should be invoked on the calling thread's looper.
     */
     */
    public void setOnKeysChangeListener(
    public void setOnKeyStatusChangeListener(
            @Nullable OnKeysChangeListener listener, @Nullable Handler handler) {
            @Nullable OnKeyStatusChangeListener listener, @Nullable Handler handler) {
        if (listener != null) {
        if (listener != null) {
            Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
            Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
            if (looper != null) {
            if (looper != null) {
@@ -307,14 +307,14 @@ public final class MediaDrm {
                }
                }
            }
            }
        }
        }
        mOnKeysChangeListener = listener;
        mOnKeyStatusChangeListener = listener;
    }
    }


    /**
    /**
     * Interface definition for a callback to be invoked when the keys in a drm
     * Interface definition for a callback to be invoked when the keys in a drm
     * session change states.
     * session change states.
     */
     */
    public interface OnKeysChangeListener
    public interface OnKeyStatusChangeListener
    {
    {
        /**
        /**
         * Called when the keys in a session change status, such as when the license
         * Called when the keys in a session change status, such as when the license
@@ -328,64 +328,64 @@ public final class MediaDrm {
         *     which may trigger an attempt to resume playback on the media stream
         *     which may trigger an attempt to resume playback on the media stream
         *     if it is currently blocked waiting for a key.
         *     if it is currently blocked waiting for a key.
         */
         */
        void onKeysChange(
        void onKeyStatusChange(
                @NonNull MediaDrm md, @NonNull byte[] sessionId,
                @NonNull MediaDrm md, @NonNull byte[] sessionId,
                @NonNull List<KeyStatus> keyInformation,
                @NonNull List<KeyStatus> keyInformation,
                boolean hasNewUsableKey);
                boolean hasNewUsableKey);
    }
    }


    /**
     * Defines the status of a key.
     * A KeyStatus for each key in a session is provided to the
     * {@link OnKeyStatusChangeListener#onKeyStatusChange}
     * listener.
     */
    public static final class KeyStatus {
        private final byte[] mKeyId;
        private final int mStatusCode;

        /**
        /**
         * The key is currently usable to decrypt media data
         * The key is currently usable to decrypt media data
         */
         */
    public static final int KEY_STATUS_USABLE = 0;
        public static final int STATUS_USABLE = 0;


        /**
        /**
         * The key is no longer usable to decrypt media data because its
         * The key is no longer usable to decrypt media data because its
         * expiration time has passed.
         * expiration time has passed.
         */
         */
    public static final int KEY_STATUS_EXPIRED = 1;
        public static final int STATUS_EXPIRED = 1;


        /**
        /**
         * The key is not currently usable to decrypt media data because its
         * The key is not currently usable to decrypt media data because its
         * output requirements cannot currently be met.
         * output requirements cannot currently be met.
         */
         */
    public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2;
        public static final int STATUS_OUTPUT_NOT_ALLOWED = 2;


        /**
        /**
         * The status of the key is not yet known and is being determined.
         * The status of the key is not yet known and is being determined.
         * The status will be updated with the actual status when it has
         * The status will be updated with the actual status when it has
         * been determined.
         * been determined.
         */
         */
    public static final int KEY_STATUS_PENDING = 3;
        public static final int STATUS_PENDING = 3;


        /**
        /**
         * The key is not currently usable to decrypt media data because of an
         * The key is not currently usable to decrypt media data because of an
         * internal error in processing unrelated to input parameters.  This error
         * internal error in processing unrelated to input parameters.  This error
         * is not actionable by an app.
         * is not actionable by an app.
         */
         */
    public static final int KEY_STATUS_INTERNAL_ERROR = 4;
        public static final int STATUS_INTERNAL_ERROR = 4;


        /** @hide */
        /** @hide */
        @IntDef({
        @IntDef({
        KEY_STATUS_USABLE,
            STATUS_USABLE,
        KEY_STATUS_EXPIRED,
            STATUS_EXPIRED,
        KEY_STATUS_OUTPUT_NOT_ALLOWED,
            STATUS_OUTPUT_NOT_ALLOWED,
        KEY_STATUS_PENDING,
            STATUS_PENDING,
        KEY_STATUS_INTERNAL_ERROR,
            STATUS_INTERNAL_ERROR,
        })
        })
        @Retention(RetentionPolicy.SOURCE)
        @Retention(RetentionPolicy.SOURCE)
        public @interface KeyStatusCode {}
        public @interface KeyStatusCode {}


    /**
     * Defines the status of a key.
     * A KeyStatus for each key in a session is provided to the
     * {@link OnKeysChangeListener#onKeysChange}
     * listener.
     */
    public static final class KeyStatus {
        private final byte[] mKeyId;
        private final int mStatusCode;

        KeyStatus(@NonNull byte[] keyId, @KeyStatusCode int statusCode) {
        KeyStatus(@NonNull byte[] keyId, @KeyStatusCode int statusCode) {
            mKeyId = keyId;
            mKeyId = keyId;
            mStatusCode = statusCode;
            mStatusCode = statusCode;
@@ -393,6 +393,9 @@ public final class MediaDrm {


        /**
        /**
         * Returns the status code for the key
         * Returns the status code for the key
         * @return one of {@link #STATUS_USABLE}, {@link #STATUS_EXPIRED},
         * {@link #STATUS_OUTPUT_NOT_ALLOWED}, {@link #STATUS_PENDING}
         * or {@link #STATUS_INTERNAL_ERROR}.
         */
         */
        @KeyStatusCode
        @KeyStatusCode
        public int getStatusCode() { return mStatusCode; }
        public int getStatusCode() { return mStatusCode; }
@@ -484,7 +487,7 @@ public final class MediaDrm {


    private static final int DRM_EVENT = 200;
    private static final int DRM_EVENT = 200;
    private static final int EXPIRATION_UPDATE = 201;
    private static final int EXPIRATION_UPDATE = 201;
    private static final int KEYS_CHANGE = 202;
    private static final int KEY_STATUS_CHANGE = 202;


    private class EventHandler extends Handler
    private class EventHandler extends Handler
    {
    {
@@ -522,8 +525,8 @@ public final class MediaDrm {
                }
                }
                return;
                return;


            case KEYS_CHANGE:
            case KEY_STATUS_CHANGE:
                if (mOnKeysChangeListener != null) {
                if (mOnKeyStatusChangeListener != null) {
                    if (msg.obj != null && msg.obj instanceof Parcel) {
                    if (msg.obj != null && msg.obj instanceof Parcel) {
                        Parcel parcel = (Parcel)msg.obj;
                        Parcel parcel = (Parcel)msg.obj;
                        byte[] sessionId = parcel.createByteArray();
                        byte[] sessionId = parcel.createByteArray();
@@ -531,9 +534,9 @@ public final class MediaDrm {
                            List<KeyStatus> keyStatusList = keyStatusListFromParcel(parcel);
                            List<KeyStatus> keyStatusList = keyStatusListFromParcel(parcel);
                            boolean hasNewUsableKey = (parcel.readInt() != 0);
                            boolean hasNewUsableKey = (parcel.readInt() != 0);


                            Log.i(TAG, "Drm keys change");
                            Log.i(TAG, "Drm key status changed");
                            mOnKeysChangeListener.onKeysChange(mMediaDrm, sessionId, keyStatusList,
                            mOnKeyStatusChangeListener.onKeyStatusChange(mMediaDrm, sessionId,
                                    hasNewUsableKey);
                                    keyStatusList, hasNewUsableKey);
                        }
                        }
                    }
                    }
                }
                }
@@ -640,6 +643,14 @@ public final class MediaDrm {
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    public @interface KeyType {}
    public @interface KeyType {}


    /**
     * Contains the opaque data an app uses to request keys from a license server
     */
    public static final class KeyRequest {
        private byte[] mData;
        private String mDefaultUrl;
        private int mRequestType;

        /**
        /**
         * Key request type is initial license request
         * Key request type is initial license request
         */
         */
@@ -664,14 +675,6 @@ public final class MediaDrm {
        @Retention(RetentionPolicy.SOURCE)
        @Retention(RetentionPolicy.SOURCE)
        public @interface RequestType {}
        public @interface RequestType {}


    /**
     * Contains the opaque data an app uses to request keys from a license server
     */
    public static final class KeyRequest {
        private byte[] mData;
        private String mDefaultUrl;
        private int mRequestType;

        KeyRequest() {}
        KeyRequest() {}


        /**
        /**
@@ -707,6 +710,8 @@ public final class MediaDrm {


        /**
        /**
         * Get the type of the request
         * Get the type of the request
         * @return one of {@link #REQUEST_TYPE_INITIAL},
         * {@link #REQUEST_TYPE_RENEWAL} or {@link #REQUEST_TYPE_RELEASE}
         */
         */
        @RequestType
        @RequestType
        public int getRequestType() { return mRequestType; }
        public int getRequestType() { return mRequestType; }
+11 −11
Original line number Original line Diff line number Diff line
@@ -99,7 +99,7 @@ struct EventTypes {
struct EventWhat {
struct EventWhat {
    jint kWhatDrmEvent;
    jint kWhatDrmEvent;
    jint kWhatExpirationUpdate;
    jint kWhatExpirationUpdate;
    jint kWhatKeysChange;
    jint kWhatKeyStatusChange;
} gEventWhat;
} gEventWhat;


struct KeyTypes {
struct KeyTypes {
@@ -221,7 +221,7 @@ void JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra,
            jwhat = gEventWhat.kWhatExpirationUpdate;
            jwhat = gEventWhat.kWhatExpirationUpdate;
            break;
            break;
         case DrmPlugin::kDrmPluginEventKeysChange:
         case DrmPlugin::kDrmPluginEventKeysChange:
            jwhat = gEventWhat.kWhatKeysChange;
            jwhat = gEventWhat.kWhatKeyStatusChange;
            break;
            break;
        default:
        default:
            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
            ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
@@ -609,8 +609,8 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {
    gEventWhat.kWhatDrmEvent = env->GetStaticIntField(clazz, field);
    gEventWhat.kWhatDrmEvent = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "EXPIRATION_UPDATE", "I");
    GET_STATIC_FIELD_ID(field, clazz, "EXPIRATION_UPDATE", "I");
    gEventWhat.kWhatExpirationUpdate = env->GetStaticIntField(clazz, field);
    gEventWhat.kWhatExpirationUpdate = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "KEYS_CHANGE", "I");
    GET_STATIC_FIELD_ID(field, clazz, "KEY_STATUS_CHANGE", "I");
    gEventWhat.kWhatKeysChange = env->GetStaticIntField(clazz, field);
    gEventWhat.kWhatKeyStatusChange = env->GetStaticIntField(clazz, field);


    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_STREAMING", "I");
    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_STREAMING", "I");
    gKeyTypes.kKeyTypeStreaming = env->GetStaticIntField(clazz, field);
    gKeyTypes.kKeyTypeStreaming = env->GetStaticIntField(clazz, field);
@@ -619,13 +619,6 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {
    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I");
    GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I");
    gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field);
    gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field);


    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I");
    gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I");
    gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I");
    gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field);

    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_NONE", "I");
    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_NONE", "I");
    gCertificateTypes.kCertificateTypeNone = env->GetStaticIntField(clazz, field);
    gCertificateTypes.kCertificateTypeNone = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_X509", "I");
    GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_X509", "I");
@@ -636,6 +629,13 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {
    GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
    GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
    GET_FIELD_ID(gFields.keyRequest.requestType, clazz, "mRequestType", "I");
    GET_FIELD_ID(gFields.keyRequest.requestType, clazz, "mRequestType", "I");


    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I");
    gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I");
    gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field);
    GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I");
    gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field);

    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
    FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
    GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B");
    GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B");
    GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
    GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");